some tips to improve developer experience with symfony
DESCRIPTION
Slides from my talk at PHP User group Minsk (Oct 30 2014)TRANSCRIPT
Some tips to improve developer experience
with Symfonyby 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('[email protected]');
$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 App\Entity\User;
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
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">Metadata\Driver\FileLocator
</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
Check new bundles while your drinking your morning coffee
http://knpbundles.com/
27
Check new bundles while your drinking your morning coffee
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