Slide 1

Slide 1 text

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.

Slide 29

Slide 29 text

BUNDLES & COMPONENTS/LIBRAIRIES BUNDLES & COMPONENTS/LIBRAIRIES Symfony\Bundle\FrameworkBundle\DependencyInjection Symfony\Component\DependencyInjection Symfony\Bundle\FrameworkBundle\Validator Symfony\Component\Validator Symfony\Bundle\FrameworkBundle\HttpKernel Symfony\Component\HttpKernel Symfony\Bundle\TwigBundle \Twig

Slide 30

Slide 30 text

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.

Slide 31

Slide 31 text

TEMPLATING TEMPLATING Follow’s 😉 Grégoire Pineau advices Grégoire Pineau advices

Slide 32

Slide 32 text

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)

Slide 56

Slide 56 text

ASSETS ASSETS Use Assetic

Slide 57

Slide 57 text

EXTENSIBILITY / MAINTAINABILITY EXTENSIBILITY / MAINTAINABILITY

Slide 58

Slide 58 text

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.

Slide 86

Slide 86 text

QUESTIONS ? QUESTIONS ?

Slide 87

Slide 87 text

THANK YOU ! THANK YOU !