KEMBAR78
Some tips to improve developer experience with Symfony | PDF
Some tips to improve 
developer experience 
with Symfony 
by Artem Kolesnikov (@tyomo4ka) 
1
Common 
recommendations 
2
Code style 
• Symfony uses PSR-1 and PSR-2 
• Symfony extends PSRs with Symfony Coding 
Standards 
• PHP CS Fixer supports PSRs and Symfony 
• Broken windows theory 
3
Prefer clean naming to 
comments 
• "Every time you write a comment, you should 
grimace and feel the failure of your ability of 
expression." © Robert C. Martin "Clean code" 
• Always comment complex and not obvious logic 
• Remove obsolete comments 
• Never commit commented unused code 
4
Avoid business logic in 
controllers 
• Fat stupid ugly controllers (FSUC) 
// FSUC 
public function updateUserAction(User $user, $userData) 
{ 
$user->updateFromArray($userData); 
$this->getDoctrine()->getManager()->flush($user); 
} 
// OK 
public function updateUserAction(User $user, $userData) 
{ 
$this->get('user_manager')->update($user, $userData); 
} 
5
Use PHP Storm IDE 
• Code analysis 
• Great Symfony2 plugin 
• Plugins for Behat, composer 
• And much, much more 
6
Use PHP syntax sugar and 
new features 
• Short syntax for arrays 
• Other syntactic sugar 
• Traits 
$options = ['yes', 'no']; 
$user = (new User())->setEmail('tyomo4ka@gmail.com'); 
$headers = $this->getRequest()['headers']; 
return $result ?: []; 
7
Don't use interfaces when 
you don't need it 
• Dependency on abstract class works as well 
• Introduce interface is much simpler than remove 
• Interfaces for everything... 
8
Symfony specific 
recommendations 
9
Don't inject service container 
in business logic services 
/** Service which does not depend on Container */ 
class UserManager 
{ 
private $em; 
public function __construct(EntityManager $em) 
{ 
$this->em = $em; 
} 
} 
/** Service which depends on Container */ 
class UserManager 
{ 
private $container; 
public function __construct(ContainerInterface $container) 
{ 
$this->container = $container; 
} 
} 
10
Use one bundle for 
application 
• Recommendation from 
"Official Symfony Best 
Practices" 
• AppBundle vs App 
• use AppEntityUser; 
11
Always use param 
converters 
• Param convert works using request attributes 
public function someAction(ContextEntity $entity) {} 
• Don't write action like this 
public function deleteTagAction() 
{ 
$this->get('xxx.tag_manager')->deleteTagFromStream( 
$this->getRequest()->get('stream_id'), 
$this->getRequest()->get('tag_id') 
); 
} 
• This looks much cleaner 
public function deleteTagAction(Stream $stream, Tag $tag) 
{ 
$this->get('xxx.tag_manager') 
->deleteTagFromStream($stream, $tag) 
; 
} 
12
Prefer security voters to ACL 
• Each ACL check requires requests to DB 
• Voters are simple 
interface VoterInterface 
{ 
function supportsAttribute($attribute); 
function supportsClass($class); 
function vote(TokenInterface $token, $object, array $attributes); 
} 
• Abstract voter (Symfony 2.6+) 
abstract class AbstractVoter implements VoterInterface 
{ 
abstract protected function getSupportedClasses(); 
abstract protected function getSupportedAttributes(); 
abstract protected function isGranted($attribute, $object, $user = null); 
} 
13
Prefer Grunt or Gulp to Assetic 
if you have reach front-end 
• Assetic is good if you don't have too much 
assets 
• Cool like a Frontend Developer: Grunt, 
RequireJS, Bower and other Tools by Ryan 
Weaver (slides and video) 
14
Recommendations from 
"Official Symfony Best 
Practices" 
15
Always use Composer 
to install Symfony 
16
Configuration management 
• Use constants to define configuration options 
that rarely change 
• Don't define a semantic dependency injection 
configuration for your bundles 
17
Services definitions 
• The name of your application's services should be 
as short as possible, ideally just one simple word 
• Use the YAML format to define your own services 
• Don't define parameters for the classes of your 
services 
<parameter key="jms_serializer.metadata.file_locator.class"> 
MetadataDriverFileLocator 
</parameter> 
18
Configuration format 
• Use annotations to define the mapping 
information of the Doctrine entities 
• Use annotations to configure routing, caching 
and security whenever possible 
• Don't use the @Template() annotation to 
configure the template used by the controller 
19
Templating 
• Use Twig templating format for your templates 
• PHP templating engine will be removed in the 
future 
• Store all your application's templates in app/ 
Resources/views/ directory 
20
Some other official recommendations 
• Define your forms as PHP classes 
• Always use keys for translations instead of 
content strings 
{{ 'project_name' |trans }} // Good 
{{ 'Project name' |trans }} // Not good 
21
Some services to improve 
quality of your projects 
22
Codeship CI 
http://codeship.io 
23
Travis CI 
https://travis-ci.org/ 
24
SensioLabs Insight 
https://insight.sensiolabs.com/ 
25
Scrutinizer CI 
https://scrutinizer-ci.com 
26
Check new bundles while 
your drinking your morning coffee 
Check new bundles while your drinking 
your morning coffee 
http://knpbundles.com/ 
27
And finally my favorite 
joke about developers :) 
28
The first year 
29
The second year 
30
The third year 
31
The fifth year 
32
The tens year 
33
Thanks! 
34

Some tips to improve developer experience with Symfony

  • 1.
    Some tips toimprove developer experience with Symfony by Artem Kolesnikov (@tyomo4ka) 1
  • 2.
  • 3.
    Code style •Symfony uses PSR-1 and PSR-2 • Symfony extends PSRs with Symfony Coding Standards • PHP CS Fixer supports PSRs and Symfony • Broken windows theory 3
  • 4.
    Prefer clean namingto comments • "Every time you write a comment, you should grimace and feel the failure of your ability of expression." © Robert C. Martin "Clean code" • Always comment complex and not obvious logic • Remove obsolete comments • Never commit commented unused code 4
  • 5.
    Avoid business logicin controllers • Fat stupid ugly controllers (FSUC) // FSUC public function updateUserAction(User $user, $userData) { $user->updateFromArray($userData); $this->getDoctrine()->getManager()->flush($user); } // OK public function updateUserAction(User $user, $userData) { $this->get('user_manager')->update($user, $userData); } 5
  • 6.
    Use PHP StormIDE • Code analysis • Great Symfony2 plugin • Plugins for Behat, composer • And much, much more 6
  • 7.
    Use PHP syntaxsugar and new features • Short syntax for arrays • Other syntactic sugar • Traits $options = ['yes', 'no']; $user = (new User())->setEmail('tyomo4ka@gmail.com'); $headers = $this->getRequest()['headers']; return $result ?: []; 7
  • 8.
    Don't use interfaceswhen you don't need it • Dependency on abstract class works as well • Introduce interface is much simpler than remove • Interfaces for everything... 8
  • 9.
  • 10.
    Don't inject servicecontainer in business logic services /** Service which does not depend on Container */ class UserManager { private $em; public function __construct(EntityManager $em) { $this->em = $em; } } /** Service which depends on Container */ class UserManager { private $container; public function __construct(ContainerInterface $container) { $this->container = $container; } } 10
  • 11.
    Use one bundlefor application • Recommendation from "Official Symfony Best Practices" • AppBundle vs App • use AppEntityUser; 11
  • 12.
    Always use param converters • Param convert works using request attributes public function someAction(ContextEntity $entity) {} • Don't write action like this public function deleteTagAction() { $this->get('xxx.tag_manager')->deleteTagFromStream( $this->getRequest()->get('stream_id'), $this->getRequest()->get('tag_id') ); } • This looks much cleaner public function deleteTagAction(Stream $stream, Tag $tag) { $this->get('xxx.tag_manager') ->deleteTagFromStream($stream, $tag) ; } 12
  • 13.
    Prefer security votersto ACL • Each ACL check requires requests to DB • Voters are simple interface VoterInterface { function supportsAttribute($attribute); function supportsClass($class); function vote(TokenInterface $token, $object, array $attributes); } • Abstract voter (Symfony 2.6+) abstract class AbstractVoter implements VoterInterface { abstract protected function getSupportedClasses(); abstract protected function getSupportedAttributes(); abstract protected function isGranted($attribute, $object, $user = null); } 13
  • 14.
    Prefer Grunt orGulp to Assetic if you have reach front-end • Assetic is good if you don't have too much assets • Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools by Ryan Weaver (slides and video) 14
  • 15.
    Recommendations from "OfficialSymfony Best Practices" 15
  • 16.
    Always use Composer to install Symfony 16
  • 17.
    Configuration management •Use constants to define configuration options that rarely change • Don't define a semantic dependency injection configuration for your bundles 17
  • 18.
    Services definitions •The name of your application's services should be as short as possible, ideally just one simple word • Use the YAML format to define your own services • Don't define parameters for the classes of your services <parameter key="jms_serializer.metadata.file_locator.class"> MetadataDriverFileLocator </parameter> 18
  • 19.
    Configuration format •Use annotations to define the mapping information of the Doctrine entities • Use annotations to configure routing, caching and security whenever possible • Don't use the @Template() annotation to configure the template used by the controller 19
  • 20.
    Templating • UseTwig templating format for your templates • PHP templating engine will be removed in the future • Store all your application's templates in app/ Resources/views/ directory 20
  • 21.
    Some other officialrecommendations • Define your forms as PHP classes • Always use keys for translations instead of content strings {{ 'project_name' |trans }} // Good {{ 'Project name' |trans }} // Not good 21
  • 22.
    Some services toimprove quality of your projects 22
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
    Check new bundleswhile your drinking your morning coffee Check new bundles while your drinking your morning coffee http://knpbundles.com/ 27
  • 28.
    And finally myfavorite joke about developers :) 28
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.