Symfony best practices

Here is a digest of the best practices that are commonly followed for Symfony2 projects. They are given as is, in no particular order and are far from being exhaustive.

Naming things

  • find a common naming scheme for your team and stick to it
    • be explicit
    • be consistent
  • same for routes and services naming
    • use service alias: mailer is better than swiftmailer.mailer.default
  • prefer Vendor/Bundle/CoolBundle over Vendor/CoolBundle for bundles namespace
    • for an application, you can even skip the vendor part

Config

Which configuration format should you use?

  • bundles config: YAML
  • routes: YAML
  • entities: YAML/XML
  • validation, serializer: YAML
  • services: YAML (XML for some use cases)

Create a routing.yml file per bundle and import it in app/config/routing.yml. Nest your routing files using prefixes.

Split vendor bundles configurations and import them in app/config/config.yml.
Split validation configuration files.

Bundles

  • should be self-contained
  • should provide a feature, not an app (examples: Forum, Admin, …)
  • should follow bundles structure standards

Controllers

  • should be lightweight
    • do not put logic in them, write handlers/services instead
  • avoid extending FrameworkBundle/Controller (expecially if your controller is meant to be distributed)
    • see http://richardmiller.co.uk/2011/06/14/symfony2-moving-away-from-the-base-controller/
    • define them as services
  • inject the request into controller actions parameters
  • do not hesitate to dispatch events for “add-on actions”
  • use Form handlers/persistence handlers

DependencyInjection

  • do not inject the Container (except for some scope-related use cases)
  • split services definition into several files
    • bonus: easy dynamic loading of services (per env for instance)
  • use a semantic configuration
  • inject configuration parameters in your services
  • environment variables (defined in apache/nginx) can be used!
  • know how tagged services and compiler passes work

Dependencies management

  • (learn how-to) use composer
  • group you dependencies by “theme” in your composer.json
  • do not commit your vendor directory or composer.phar, only commit composer.json and composer.lock
  • use composer.phar install --no-dev --optimize-autoloader --prefer-dist in prod
  • do not require dev-master unless you absolutely have to
  • use bounded versions constraints
    • BAD : >=1.2.0
    • GOOD: >=1.2.0,<2.0.0
    • BETTER: ~1.2
  • know about composer stability flags
  • avoid optional dependencies

Forms

  • use Type classes
  • always set a default data_class
  • define types as services
  • do not disable CSRF (except for API)
  • set the intention option

Doctrine

  • activate caches: metadata cache, query cache, result cache
    • and don’t forget to clear these caches when you deploy
  • register repositories as services and inject them
  • do not write queries outside repositories
  • only flush from the controller

Tools

Useful bundles

Miscellaneous