The definitive guide of Symfony 1.0

5.1. The Configuration System

Regardless of purpose, most web applications share a common set of characteristics. For instance, some sections can be restricted to a subset of users, or the pages can be decorated by a layout, or a form can be filled with the user input after a failed validation. A framework defines a structure for emulating these characteristics, and the developer can further tweak them by changing a configuration setting. This strategy saves a lot of development time, since many changes don't require a single line of code, even if there is a lot of code behind. It is also much more efficient, because it ensures such information can be maintained in a single and easily identifiable location.

However, this approach has two serious drawbacks:

  • Developers end up writing endlessly complex XML files.
  • In a PHP architecture, every request takes much longer to process.

Taking these disadvantages into account, symfony uses configuration files only for what they are best at doing. As a matter of fact, the ambition of the configuration system in symfony is to be:

  • Powerful: Almost every aspect that can be managed using configuration files is managed using configuration files.
  • Simple: Many aspects of configuration are not shown in a normal application, since they seldom need to be changed.
  • Easy: Configuration files are easy to read, to modify, and to create by the developer.
  • Customizable: The default configuration language is YAML, but it can be INI, XML, or whatever format the developer prefers.
  • Fast: The configuration files are never processed by the application but by the configuration system, which compiles them into a fast-processing chunk of code for the PHP server.

5.1.1. YAML Syntax and Symfony Conventions

For its configuration, symfony uses the YAML format by default, instead of more traditional INI or XML formats. YAML shows structure through indentation and is fast to write. Its advantages and basic rules were already described in Chapter 1. However, you need to keep a few conventions in mind when writing YAML files. This section introduces several of the most prominent conventions. For a complete dissertation on the topic, visit the YAML website (yaml.org).

First of all, never use tabs in YAML files; use spaces instead. YAML parsers can't understand files with tabs, so indent your lines with spaces (a double blank is the symfony convention for indentation), as shown in Listing 5-1.

Listing 5-1 - YAML Files Forbid Tabs

# Never use tabs
all:
-> mail:
-> -> webmaster:  [email protected]

# Use blanks instead
all:
  mail:
    webmaster: [email protected]

If your parameters are strings starting or ending with spaces, enclose the value in single quotes. If a string parameter contains special characters, also enclose the value in single quotes, as shown in Listing 5-2.

Listing 5-2 - Nonstandard Strings Should Be Enclosed in Single Quotes

error1: This field is compulsory
error2: '  This field is compulsory  '
error3: 'Don''t leave this field blank'   # Single quotes must be doubled

You can define long strings in multiple lines, and also multiple-line strings, with the special string headers (> and |) plus an additional indentation. Listing 5-3 demonstrates this convention.

Listing 5-3 - Defining Long and Multiline Strings

# Folded style, introduced by >
# Each line break is folded to a space
# Makes YAML more readable
accomplishment: >
  Mark set a major league
  home run record in 1998.

# Literal style, introduced by |
# All line breaks count
# Indentation doesn't appear in the resulting string
stats: |
  65 Home Runs
  0.278 Batting Average

To define a value as an array, enclose the elements in square brackets or use the expanded syntax with dashes, as shown in Listing 5-4.

Listing 5-4 - YAML Array Syntax

# Shorthand syntax for arrays
players: [ Mark McGwire, Sammy Sosa, Ken Griffey ]

# Expanded syntax for arrays
players:
  - Mark McGwire
  - Sammy Sosa
  - Ken Griffey

To define a value as an associative array, or hash, enclose the elements in curly brackets and always insert a space between the key and the value in the key: value couple. You can also use the expanded syntax by adding indentation and a carriage return for every new key, as shown in Listing 5-5.

Listing 5-5 - YAML Associative Array Syntax

# Incorrect syntax, blanks are missing after the colon
mail: {webmaster:[email protected],contact:[email protected]}

# Correct shorthand syntax for associative arrays
mail: { webmaster: [email protected], contact: [email protected] }

# Expanded syntax for associative arrays
mail:
  webmaster: [email protected]
  contact:   [email protected]

To give a Boolean value, use either on, 1, or true for a positive value and off, 0, or false for a negative one. Listing 5-6 shows the possible Boolean values.

Listing 5-6 - YAML Boolean Values Syntax

true_values:   [ on, 1, true ]
false_values:  [ off, 0, false ]

Don't hesitate to add comments (starting with the hash mark, #) and extra spaces to values to make your YAML files more readable, as shown in Listing 5-7.

Listing 5-7 - YAML Comments Syntax and Value Alignment

# This is a comment line
mail:
  webmaster: [email protected]
  contact:   [email protected]
  admin:     [email protected]   # extra spaces allow nice alignment of values

In some symfony configuration files, you will sometimes see lines that start with a hash mark (and, as such, ignored by the YAML parsers) but look like usual settings lines. This is a symfony convention: the default configuration, inherited from other YAML files located in the symfony core, is repeated in commented lines in your application configuration, for your information. If you want to change the value of such a parameter, you need to uncomment the line first, as shown in Listing 5-8.

Listing 5-8 - Default Configuration Is Shown Commented

# The cache is off by default
settings:
# cache: off

# If you want to change this setting, uncomment the line first
settings:
  cache: on

Symfony sometimes groups the parameter definitions into categories. All settings of a given category appear indented under the category header. Structuring long lists of key: value pairs by grouping them into categories improves the readability of the configuration. Category headers start with a dot (.). Listing 5-9 shows an example of categories.

Listing 5-9 - Category Headers Look Like Keys, But Start with a Dot

all:
  .general:
    tax:        19.6

  mail:
    webmaster:  [email protected]

In this example, mail is a key and general is only a category header. Everything works as if the category header didn't exist, as shown in Listing 5-10. The tax parameter is actually a direct child of the all key. However using categories helps symfony dealing with arrays that are beneath the all key.

Listing 5-10 - Category Headers Are Only There for Readability and Are Actually Ignored

all:
  tax:          19.6

  mail:
    webmaster:  [email protected]

5.1.2. Help, a YAML File Killed My App!

The YAML files are parsed into PHP hashes and arrays, and then the values are used in various parts of the application to modify the behavior of the view, the controller, or the model. Many times, when there is a problem in a YAML file, it is not detected until the value actually needs to be used. Moreover, the error or exception that is thrown then is usually not clearly related to the YAML configuration file.

If your application suddenly stops working after a configuration change, you should check that you didn't make any of the common mistakes of the inattentive YAML coder:

You miss a space between a key and its value:

key1:value1      # A space is missing after the :

Keys in a sequence are not indented the same way:

all:
  key1:  value1
   key2: value2  # Indentation is not the same as the other sequence members
  key3:  value3

There is a reserved YAML character in a key or a value, without string delimiters:

message: tell him: go way    # :, [, ], { and } are reserved in YAML
message: 'tell him: go way'  # Correct syntax

You are modifying a commented line:

# key: value     # Will never be taken into account due to the leading #

You set values with the same key name twice at the same level:

key1: value1
key2: value2
key1: value3     # key1 is defined twice, the value is the last one defined

You think that the setting takes a special type, while it is always a string, until you convert it:

income: 12,345   # Until you convert it, this is still a string