42 BEST PRACTICES FOR
42 BEST PRACTICES FOR
SYMFONY2
SYMFONY2
Tugdual Saunier (@tucksaun)
Slide 2
Slide 2 text
DISCLAIMER
DISCLAIMER
Slide 3
Slide 3 text
What follows is not stored by meaningfulness nor criticality.
Slide 4
Slide 4 text
Of course, every best practice is questionnable.
Slide 5
Slide 5 text
There are always exceptions.
Slide 6
Slide 6 text
Be pragmatic!
Consider the context.
Slide 7
Slide 7 text
LET’S START
LET’S START
Slide 8
Slide 8 text
DOCUMENTATION
DOCUMENTATION
There’s a lot of documentation available.
Read it.
Slide 9
Slide 9 text
DOCUMENTATION
DOCUMENTATION
Have you already?
Read it again from time to time
Slide 10
Slide 10 text
DOCUMENTATION
DOCUMENTATION
When you are looking for documentation or seeking help.
Use Symfony2 (capitalize, no space).
There is so much resources available symfony (1.x) that filtering
then out would make you lose time.
Slide 11
Slide 11 text
BOOTSTRAPPING
BOOTSTRAPPING
Except if you are at ease and perfectly master Symfony2,
Use the Standard Edition.
Slide 12
Slide 12 text
BOOTSTRAPPING
BOOTSTRAPPING
Use the Standard Edition.
But do some house cleaning!
Delete AcmeDemoBundle
Removed unused dependencies
Change the favicon
etc
Slide 13
Slide 13 text
PROFILER
PROFILER
The Web Debug Toolbar gives you a lot of useful informations.
Always keep an eye on it.
Slide 14
Slide 14 text
PROFILER
PROFILER
Intercept redirection (in dev).
This will help you during debugging and will help you to have a
better view on the data collected by the profiler.
Slide 15
Slide 15 text
ORGANISATION
ORGANISATION
Slide 16
Slide 16 text
SCM IGNORE
SCM IGNORE
app/cache/*
app/logs/*
app/bootstrap.php.cache
web/bundles
vendor
app/config/parameters.yml
But for the last one, add a
app/config/parameters.yml.dist file.
Slide 17
Slide 17 text
YOUR CREDENTIALS ARE SECRET!
YOUR CREDENTIALS ARE SECRET!
Do not hardcode credentials in configuration: use parameters
Do not version parameters.[ini|yml]
Use environment variables
Slide 18
Slide 18 text
YOUR CREDENTIALS ARE SECRET!
YOUR CREDENTIALS ARE SECRET!
# app/config/config.yml
doctrine:
dbal:
username: %database_username%
password: %database_password%
Slide 19
Slide 19 text
YOUR CREDENTIALS ARE SECRET!
YOUR CREDENTIALS ARE SECRET!
# app/config/parameters.yml
parameters:
database_username: symfony
database_password: s3cr3t
Slide 20
Slide 20 text
YOUR CREDENTIALS ARE SECRET!
YOUR CREDENTIALS ARE SECRET!
Servername www.domain.tld
# ...
SetEnv SYMFONY__DATABASE_USERNAME "symfony"
SetEnv SYMFONY__DATABASE_PASSWORD "s3cr3t"
Slide 21
Slide 21 text
YOUR CREDENTIALS ARE SECRET!
YOUR CREDENTIALS ARE SECRET!
This is not limited to passwords, apply for any “secret”
information.
Slide 22
Slide 22 text
CODING STYLE
CODING STYLE
Always use the same coding style.
Better, follow Symfony’s one.
Slide 23
Slide 23 text
CODING STYLE
CODING STYLE
A must-have tool is available to help your to respect Symfony’s
coding style:
PHP Coding Standards Fixer
https://cs.symfony.com/
https://cs.symfony.com/
Slide 24
Slide 24 text
APPLICATIONS? APPLICATION!
APPLICATIONS? APPLICATION!
By default, Symfony2 has a single application.
It is quite unusual to need several ones, think thoroughly before
implementing a multiple applications setup.
Slide 25
Slide 25 text
APPLICATIONS
APPLICATIONS
If you really want to use several applications,
your tree directory must be uniform and mimic as much as
possible the Standard Edition one (app directory).
Slide 26
Slide 26 text
BUNDLES
BUNDLES
Your project is composed of Bundles.
Slide 27
Slide 27 text
BUNDLES
BUNDLES
One Bundle = One feature
If your bundles are meant to be re-used
and if your bundles are de-coupled.
UserBundle => User Management
ForumBundle => Forum
ProductBundle => Product Management
StoreBundle => E-Commerce
Slide 28
Slide 28 text
BUNDLES & COMPONENTS/LIBRAIRIES
BUNDLES & COMPONENTS/LIBRAIRIES
In an ideal world, your bundles should only be the glue between
Symfony2 and your business logic.
The business logic must be independent.
Take inspiration from the Bundles and Components organization
in Symfony2.
ROUTING
ROUTING
No route should be declared in app/config/routing.yml.
This file should only contain imports. Route declarations should
be stored in the bundle of the associated controller.
I18N
I18N
Introduce internationalization from the get go
Introducing internationalization later one takes more time is and
is more complicated.
Slide 33
Slide 33 text
CONTROLLERS
CONTROLLERS
Slide 34
Slide 34 text
FORMS
FORMS
After a successful form processing in POST, you must always
redirect the user:
security
UX
avoid double submission and data duplication
Slide 35
Slide 35 text
ORM
ORM
Queries must be created withing dedicated classes (Repository,
Peer), not directly in controllers.
Slide 36
Slide 36 text
COMPULSORY
COMPULSORY
No business logic in controllers.
They must fetch services (or instantiate business objects), invoke
them, and provide processing result to the view layer.
That’s it.
Slide 37
Slide 37 text
LENGTH
LENGTH
20 lines max per action.
More usually means they contain business logic.
No more than 10 actions per controller.
More than that and it becomes un-maintenable.
Slide 38
Slide 38 text
LENGTH
LENGTH
Annotations can help to keep you controllers lighter and with
less boilerplate.
They also help you to centralize information and keep route
declaration with the associated controller.
Slide 39
Slide 39 text
MODEL
MODEL
Slide 40
Slide 40 text
“UTILS”
“UTILS”
Do not create “util” classes with tons of static methods.
Slide 41
Slide 41 text
FORMS
FORMS
Build your form in Form Types
Reusable
Do not clutter your controllers
“Cleaner” organisation
Slide 42
Slide 42 text
FORMS
FORMS
Declare those types as services.
Slide 43
Slide 43 text
FORMS
FORMS
If your fom types have dependencies, inject them into the
constructor, not using options.
Slide 44
Slide 44 text
SESSIONS
SESSIONS
The session use logic must be in a service with the session
injected.
Not in controllers.
Slide 45
Slide 45 text
SESSIONS
SESSIONS
Minimise the amount of data you store in sessions.
Slide 46
Slide 46 text
LOGGING
LOGGING
The default Monolog configuration will only output debug logs if
an error happens.
Therefore do not refrain yourself to log.
Slide 47
Slide 47 text
ORM
ORM
Use your entities to store information.
Use dedicated business classes to manipulate them.
“Treat your entities like princesses”.
This eases unit testing, refactoring and bundles/component
organisation.
Slide 48
Slide 48 text
DIC
DIC
Slide 49
Slide 49 text
DIC
DIC
The DIC is without any doubts the most powerful tool in
Symfony2.
Symfony2 flexibility comes from the DIC.
Read, learn, try!
Slide 50
Slide 50 text
DIC
DIC
Use XML configuration for you bundles.
Slide 51
Slide 51 text
DIC
DIC
Do not inject the container.
Only inject the required dependencies.
Slide 52
Slide 52 text
DIC
DIC
Do not hardcode paths.
You can use the %kernel.root_dir% parameter or build
paths during DIC compilation.
Slide 53
Slide 53 text
VIEWS
VIEWS
Slide 54
Slide 54 text
USE TWIG
USE TWIG
This will constrain you to respect MVC
Slide 55
Slide 55 text
USE TWIG
USE TWIG
Intuitive
Performant
Powerful
Secured (Autoescaping)
BUNDLES
BUNDLES
You should not import your bundle’s configuration from
app/config/config.yml.
The bundle’s DI extension should take care of it.
Slide 59
Slide 59 text
BUNDLES
BUNDLES
Use the semantic configuration
# app/config/config.yml
my_bundle:
foo: bar
my_feat_is_enabled: true
feat_config:
lorem: ipsum
Slide 60
Slide 60 text
BUNDLES
BUNDLES
Validating this configuration let you:
enable your services only if necessary,
ensure your configuration is valid during warmup…
and give explicit error messages to developer.
Slide 61
Slide 61 text
COMMANDS
COMMANDS
Use Commands for your batch processing and repetitive tasks.
Slide 62
Slide 62 text
TESTS
TESTS
Use unit and functional tests!
Slide 63
Slide 63 text
PROD
PROD
Slide 64
Slide 64 text
FRONT CONTROLLER
FRONT CONTROLLER
Don’t deploy web/app_dev.php
To be more accurate, the only front controller to deploy is
web/app.php
Slide 65
Slide 65 text
FORMS
FORMS
Do not disable CSRF protection.
Slide 66
Slide 66 text
FORMS
FORMS
Change the secret value in parameters.yml!
Slide 67
Slide 67 text
FORMS
FORMS
Remenber, “Your credentials are secret!”.
The secret also is!
(Hence the name…)
Slide 68
Slide 68 text
FORMS
FORMS
Go further, use the intention option in your forms.
This will make the token unique for each form type.
Slide 69
Slide 69 text
DOCTRINE
DOCTRINE
Enable Doctrine caches (metadata and query).
No functional effect, only better performance.
Slide 70
Slide 70 text
CUSTOMIZE YOUR ERROR PAGES
CUSTOMIZE YOUR ERROR PAGES
That’s classy
Avoid default page to be recognized
Slide 71
Slide 71 text
LOGS
LOGS
Monolog’s configuration is really good for production.
Do not enable log output for every requests.
Slide 72
Slide 72 text
CACHING
CACHING
Page caching is simple with Symfony2.
Do not generate the same content twice, use caching.
Slide 73
Slide 73 text
PHP
PHP
Use PHP 5.4.
You will save on time and memory.
Slide 74
Slide 74 text
PHP
PHP
Install and enable APC.
You will save on time.
(Should not be necessary anymore with PHP 5.5
😉 )
Slide 75
Slide 75 text
FINALLY
FINALLY
Slide 76
Slide 76 text
No content
Slide 77
Slide 77 text
No content
Slide 78
Slide 78 text
No content
Slide 79
Slide 79 text
Do not forget that Symfony2 is a PHP Object Framework
Slide 80
Slide 80 text
Therefore, do not ask yourself
“How to do this with Symfony2 ?”,
but ask yourself
“How to do this using PHP Object ?”.
Slide 81
Slide 81 text
Follow PHP best practices.
Follow OOP best practices.
Slide 82
Slide 82 text
No references
No globals
No short tags
Type Hinting
UTF-8
PSR-x
…
Slide 83
Slide 83 text
but also CSS, HTML, JavaScript, Twig, etc …
Slide 84
Slide 84 text
to summarize: also follow best practices for every tool you use,
Slide 85
Slide 85 text
but also the one for the web ecosystem, software development
and project management.