Configuration organization tips

How to organize the app/config directory

Who's this noob?

Emanuele Minotto

Senior Web Developer at Amara Living Ltd

   

feeling comfortable is better than best practices

(so next tips are suggestions, not rules)

Is it so important?

Keep control while the application grows

Prevent big configuration files

Be ready for changes

Importers


// app/config/common/imports.php

foreach (glob(__DIR__.'/*.yml') as $file) {
    $loader->import($file);
}
					

# app/config/config.yml

imports:
- resource: parameters.yml
- resource: security.yml
- resource: services.yml
- resource: common/imports.php
					
instead of

# app/config/config.yml

imports:
- resource: parameters.yml
- resource: security.yml
- resource: services.yml
- resource: common/fos_elastica.yml
- resource: common/fos_rest.yml
- resource: common/fos_user.yml
- resource: common/jms_serializer.yml
# - resource: common/...
# - resource: common/...
# - resource: common/...
# - resource: common/...
# - resource: common/...
					
using the vendor/bundle pattern

// app/config/common/imports.php

foreach (glob(__DIR__.'/*/*.yml') as $file) {
    $loader->import($file);
}
					

app/config/
           common/
                  imports.php
                  fos/
                      user.yml
                      rest.yml
                  jms/
                      serializer.yml
					

Default values

implicit settings are better

adapt to changes

to freeze configs, freeze composer versions

(good) bundles already fill empty/poor configurations

Developer version:

sensio_framework_extra:
  view:
    annotations: false
					
Compiled version:

sensio_framework_extra:
  view:
    annotations: false
  router:
    annotations: true
  request:
    converters: true
    auto_convert: true
  cache:
    annotations: true
  security:
    annotations: true
    expression_language: sensio_framework_extra.security.expression_language.default
  psr_message:
    enabled: false
					

Overrides


# example-1/config.yml
fos_user:
  registration:
    confirmation:
      enabled: false

# example-1/config_prod.yml
fos_user:
  registration:
    confirmation:
      enabled: true
					

wrong assertion: dev == test == * != prod


# example-2/config.yml
fos_user:
  registration:
    confirmation:
      from_email: # ...
      enabled: false

# example-2/config_prod.yml
imports:
- resource: config.yml

fos_user:
  registration:
    confirmation:
      enabled: true
					

reduced repetitions


# example-3/config.yml
fos_user:
  registration:
    confirmation:
      from_email: %confirmation_from_email%
      enabled: %confirmation_enabled%
					

variables-based configuration

environment-based configuration

Creating a bundle? Parameters are great, use them!


# common/doctrine_cache.yml
doctrine_cache:
  providers:
    foo:
      memcached:
        servers:
          memcached01.ss: 11211
    bar:
      memcached:
        servers:
          memcached01.ss: 11211
    test:
      memcached:
        servers:
          memcached01.ss: 11211
          
common solution

# common/doctrine_cache.yml
doctrine_cache:
  providers:
    foo:
      type: memcached
    bar:
      type: memcached
    test:
      type: memcached

# parameters.yml
parameters:
  doctrine_cache.memcache.host: memcached01.ss
          
best solution

Naming Strategies

Services

the identifier is the full namespace lowercase, without the Bundle suffix

underscores separate uppercase letters

(snake_case)

a dot instead of the backslash

if a class/interface is suffixed with the directory name, remove it

Examples:

  • FooBarBundle\OurPackage => foo_bar.our_package
  • AppBundle\Controller\LibraryController => app.controller.library

Thank you!

Joind.in: joind.in/event/symfonyuk-201509

References PR: git.io/vZtGa

Questions? Send me a tweet @EmanueleMinotto