Caution: You are browsing the legacy 1.x part of this website.
This version of symfony is not maintained anymore. If some of your projects still use this version, consider upgrading.
This work is licensed under the GFDL license.

Master Symfony2 fundamentals

Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).
trainings.sensiolabs.com

Discover the SensioLabs Support

Access to the SensioLabs Competency Center for an exclusive and tailor-made support on Symfony
sensiolabs.com
Blackfire Profiler Fire up your PHP Apps Performance

PHP Project Quality Done Right

Now that you know symfony very well, you are already able to dig into its code to understand its core design and discover new hidden abilities. But before extending the symfony classes to match your own requirements, you should take a closer look at some of the configuration files. Many features are already built into symfony and can be activated by just changing configuration settings. This means that you can tweak the symfony core behavior without overriding its classes. This chapter takes you deep into the configuration files and their powerful capabilities.

Symfony Settings

The myapp/config/settings.yml file contains the main symfony configuration for the myapp application. You have already seen the function of many settings from this file in the previous chapters, but let's revisit them.

As explained in Chapter 5, this file is environment-dependent, which means that each setting can take a different value for each environment. Remember that each parameter defined in this file is accessible from inside the PHP code via the sfConfig class. The parameter name is the setting name prefixed with sf_. For instance, if you want to get the value of the cache parameter, you just need to call sfConfig::get('sf_cache').

Default Modules and Actions

When a routing rule doesn't define the module or the action parameter, values from the settings.yml file are used instead:

  • default_module: Default module request parameter. Defaults to the default module.
  • default_action: Default action request parameter. Defaults to the index action.

Symfony provides default pages for special situations. In the case of a routing error, symfony executes an action of the default module, which is stored in the $sf_symfony_data_dir/modules/default/ directory. The settings.yml file defines which action is executed depending on the error:

  • error_404_module and error_404_action: Action called when the URL entered by the user doesn't match any route or when an sfError404Exception occurs. The default value is default/error404.
  • login_module and login_action: Action called when a nonauthenticated user tries to access a page defined as secure in security.yml (see Chapter 6 for details). The default value is default/login.
  • secure_module and secure_action: Action called when a user doesn't have the credentials required for an action. The default value is default/secure.
  • module_disabled_module and module_disabled_action: Action called when a user requests a module declared as disabled in module.yml. The default value is default/disabled.
  • unavailable_module and unavailable_action: Action called when a user requests a page from a disabled application. The default value is default/unavailable. To disable an application, set the available parameter to off in settings.yml.

Before deploying an application to production, you should customize these actions, because the default module templates include the symfony logo on the page. See Figure 19-1 for a screenshot of one of these pages, the error 404 page.

Figure 19-1 - Default 404 error page

Default 404 error page

You can override the default pages in two ways:

  • You can create your own default module in the application's modules/ directory, override all the actions defined in the settings.yml file (index, error404, login, secure, disabled, and unavailable) and all the related templates (indexSuccess.php, error404Success.php, loginSuccess.php, secureSuccess.php, disabledSuccess.php, and unavailableSuccess.php).
  • You can change the default module and action settings of the settings.yml file to use pages of your application.

Two other pages bear a symfony look and feel, and they also need to be customized before deployment to production. These pages are not in the default module, because they are called when symfony cannot run properly. Instead, you will find these default pages in the $sf_symfony_data_dir/web/errors/ directory:

  • error500.php: Page called when an internal server error occurs in the production environment. In other environments (where SF_DEBUG is set to true), when an error occurs, symfony displays the full execution stack and an explicit error message (see Chapter 16 for details).
  • unavailable.php: Page called when a user requests a page while the cache is being cleared (that is, between a call to the symfony clear-cache task and the end of this task execution). On systems with a very large cache, the cache-clearing process can take several seconds. Symfony cannot execute a request with a partially cleared cache, so requests received before the end of the process are redirected to this page.

To customize these pages, simply create error500.php and unavailable.php pages in your application's web/errors/ directory. Symfony will use these instead of its own.

note

To have requests redirected to the unavailable.php page when needed, you need to set the check_lock setting to on in the application settings.yml. The check is deactivated by default, because it adds a very slight overhead for every request.

Optional Feature Activation

Some parameters of the settings.yml file control optional framework features that can be enabled or disabled. Deactivating unused features boosts performances a bit, so make sure to review the settings listed in Table 19-1 before deploying your application.

Table 19-1 - Optional Features Set Through settings.yml

Parameter Description Default Value
use_database Enables the database manager. Set it to off if you don't use a database. on
use_security Enables security features (secure actions and credentials; see Chapter 6). The default security filter (sfBasicSecurityFilter) is enabled only if it is on. on
use_flash Enables the flash parameter feature (see Chapter 6). Set it to off if you never use the set_flash() method in your actions. The flash filter (sfFlashFilter) is enabled only if it is on. on
i18n Enables interface translation (see Chapter 13). Set it to on for multilingual applications. off
logging_enabled Enables logging of symfony events. Set it to off when you want to ignore the logging.yml settings and turn symfony logging off completely. on
escaping_strategy Enables and defines the policy of the output escaping feature (see Chapter 7). Set it to off if you don't use the $sf_data container in your templates. bc
cache Enables template caching (see Chapter 12). Set it to on if one of your modules includes cache.yml file. The cache filter (sfCacheFilter) is enabled only if it is on. off in development, on in production
web_debug Enables the web debug toolbar for easy debugging (see Chapter 16). Set it to on to display the toolbar on every page. The web debug filter (sfWebDebugFilter) is enabled only if it is on. on in development, off in production
check_symfony_version Enables the check of the symfony version for every request. Set it to on for automatic cache clearing after a framework upgrade. Leave it set to off if you always clear the cache after an upgrade. off
check_lock Enables the application lock system, triggered by the clear-cache and disable tasks (see the previous section). Set it to on to have all requests to disabled applications redirected to the $sf_symfony_data_dir/web/errors/unavailable.php page. off
compressed Enables PHP response compression. Set it to on to compress the outgoing HTML via the PHP compression handler. off
use_process_cache Enables symfony optimizations based on PHP accelerators. When such an accelerator (for instance, APC, XCache, or eAccelerator) is installed, symfony takes advantage of its features to keep objects and configuration in memory between requests. Set the parameter to off in development or when you don't want PHP accelerator optimizations. Note that even if you don't have any accelerator installed, leaving it set to on will not harm performance. on

Feature Configuration

Symfony uses some parameters of settings.yml to alter the behavior of built-in features such as form validation, cache, and third-party modules.

Output Escaping Settings

Output escaping settings control the way the variables are accessible in the template (see Chapter 7). The settings.yml file includes two settings for this feature:

  • The escaping_strategy setting can take the value bc, both, on, or off.
  • The escaping_method setting can be set to ESC_RAW, ESC_ENTITIES, ESC_JS, or ESC_JS_NO_ENTITIES.

Routing Settings

Two routing settings (see Chapter 9) are stored in settings.yml:

  • The suffix parameter sets the default suffix for generated URLs. The default value is a period (.), and it corresponds to no suffix. Set it to .html, for instance, to have all generated URLs look like static pages.
  • The no_script_name parameter enables the front controller name in generated URLs. The no_script_name setting can be on only for a single application in a project, unless you store the front controllers in various directories and alter the default URL rewriting rules. It is usually on for the production environment of your main application and off for the others.

Form Validation Settings

Form validation settings control the way error messages output by the Validation helpers look (see Chapter 10). These errors are included in <div> tags, and they use the validation_error_ class setting as a class attribute and the validation_error_id_prefix setting to build up the id attribute. The default values are form_error and error_for_, so the attributes output by a call to the form_error() helper for an input named foobar will be class="form_error" id="error_for_foobar".

Two settings determine which characters precede and follow each error message: validation_error_prefix and validation_error_suffix. You can change them to customize all error messages at once.

Cache Settings

Cache settings are defined in cache.yml for the most part, except for two in settings.yml: cache enables the template cache mechanism, and etag enables ETag handling on the server side (see Chapter 15).

Logging Settings

Two logging settings (see Chapter 16) are stored in settings.yml:

  • error_reporting specifies which events are logged in the PHP logs. By default, it is set to 341 for the production environment (so the logged events are E_PARSE, E_COMPILE_ERROR, E_ERROR, E_CORE_ERROR, and E_USER_ERROR) and to 4095 for the development environment (E_ALL and E_STRICT).
  • The web_debug setting activates the web debug toolbar. Set it to on only in the development and test environments.

Paths to Assets

The settings.yml file also stores paths to assets. If you want to use another version of the asset than the one bundled with symfony, you can change these path settings:

  • Rich text editor JavaScript files stored in rich_text_js_dir (by default, js/tiny_mce)
  • Prototype libraries stored in prototype_web_dir (by default, /sf/prototype)
  • Files needed by the administration generator stored in admin_web_dir
  • Files needed by the web debug toolbar stored in web_debug_web_dir
  • Files needed by the javascript calendar stored in calendar_web_dir

Default Helpers

Default helpers, loaded for every template, are declared in the standard_helpers setting (see Chapter 7). By default, these are the Partial, Cache, and Form helper groups. If you use a helper group in all templates of an application, adding its name to the standard_helpers setting saves you the hassle of declaring it with use_helper() on each template.

Activated Modules

Activated modules from plug-ins or from the symfony core are declared in the enabled_modules parameter. Even if a plug-in bundles a module, users can't request this module unless it is declared in enabled_modules. The default module, which provides the default symfony pages (congratulations, page not found, and so on), is the only enabled module by default.

Character Set

The character set of the responses is a general setting of the application, because it is used by many components of the framework (templates, output escaper, helpers, and so on). Defined in the charset setting, its default (and advised) value is utf-8.

Miscellaneous Configuration

The settings.yml file contains a few more parameters, used internally by symfony for core behaviors. Listing 19-1 lists them as they appear in the configuration file.

Listing 19-1 - Miscellaneous Configuration Settings, in myapp/config/settings.yml

# Remove comments in core framework classes as defined in the core_compile.yml
strip_comments:         on
# Functions called when a class is requested and not already loaded
# Expects an array of callables. Used by the framework bridges.
autoloading_functions:  ~
# Session timeout, in seconds
timeout:                1800
# Maximum number of forwards followed by the action before raising an exception
max_forwards:           5
# Global constants
path_info_array:        SERVER
path_info_key:          PATH_INFO
url_format:             PATH

sidebar

Adding Your application settings

The settings.yml file defines symfony settings for an application. As discussed in Chapter 5, when you want to add new parameters, the best place to do so is in the myapp/config/app.yml file. This file is also environment-dependent, and the settings it defines are available through the sfConfig class with the app_ prefix.

all:
  creditcards:
    fake:             off    # app_creditcards_fake
    visa:             on     # app_creditcards_visa
    americanexpress:  on     # app_creditcards_americanexpress

You can also write an app.yml file in the project configuration directory, and this provides a way to define custom project settings. The configuration cascade also applies to this file, so the settings defined in the application app.yml file override the ones defined at the project level.

Extending the Autoloading Feature

The autoloading feature, briefly explained in Chapter 2, exempts you from requiring classes in your code if they are located in specific directories. This means that you can just let the framework do the job for you, allowing it to load only the necessary classes at the appropriate time, and only when needed.

The autoload.yml file lists the paths in which autoloaded classes are stored. The first time this configuration file is processed, symfony parses all the directories referenced in the file. Each time a file ending with .php is found in one of these directories, the file path and the class names found in this file are added to an internal list of autoloading classes. This list is saved in the cache, in a file called config/config_autoload.yml.php. Then, at runtime, when a class is used, symfony looks in this list for the class path and includes the .php file automatically.

Autoloading works for all .php files containing classes and/or interfaces.

By default, classes stored in the following directories in your projects benefit from the autoloading automatically:

  • myproject/lib/
  • myproject/lib/model
  • myproject/apps/myapp/lib/
  • myproject/apps/myapp/modules/mymodule/lib

There is no autoload.yml file in the default application configuration directory. If you want to modify the framework settings--for instance, to autoload classes stored somewhere else in your file structure--create an empty autoload.yml file and override the settings of $sf_symfony_data_dir/config/autoload.yml or add your own.

The autoload.yml file must start with an autoload: key and list the locations where symfony should look for classes. Each location requires a label; this gives you the ability to override symfony's entries. For each location, provide a name (it will appear as a comment in config_autoload.yml.php) and an absolute path. Then define if the search must be recursive, which directs symfony to look in all the subdirectories for .php files, and exclude the subdirectories you want. Listing 19-2 shows the locations used by default and the file syntax.

Listing 19-2 - Default Autoloading Configuration, in $sf_symfony_data_dir/config/autoload.yml

autoload:

  # symfony core
  symfony:
    name:           symfony
    path:           %SF_SYMFONY_LIB_DIR%
    recursive:      on
    exclude:        [vendor]

  propel:
    name:           propel
    path:           %SF_SYMFONY_LIB_DIR%/vendor/propel
    recursive:      on

  creole:
    name:           creole
    path:           %SF_SYMFONY_LIB_DIR%/vendor/creole
    recursive:      on

  propel_addon:
    name:           propel addon
    files:
      Propel:       %SF_SYMFONY_LIB_DIR%/addon/propel/sfPropelAutoload.php

  # plugins
  plugins_lib:
    name:           plugins lib
    path:           %SF_PLUGINS_DIR%/*/lib
    recursive:      on

  plugins_module_lib:
    name:           plugins module lib
    path:           %SF_PLUGINS_DIR%/*/modules/*/lib
    prefix:         2
    recursive:      on

  # project
  project:
    name:           project
    path:           %SF_LIB_DIR%
    recursive:      on
    exclude:        [model, symfony]

  project_model:
    name:           project model
    path:           %SF_MODEL_LIB_DIR%
    recursive:      on

  # application
  application:
    name:           application
    path:           %SF_APP_LIB_DIR%
    recursive:      on

  modules:
    name:           module
    path:           %SF_APP_DIR%/modules/*/lib
    prefix:         1
    recursive:      on

A rule path can contain wildcards and use the file path parameters from the constants.php file (see the next section). If you use these parameters in the configuration file, they must appear in uppercase and begin and end with %.

Editing your own autoload.yml will add new locations to symfony's autoloading, but you may want to extend this mechanism and add your own autoloading handler to symfony's handler. This is possible through the autoloading_functions parameter in the settings.yml file. It expects an array of callables as a value, as follows:

.settings:
  autoloading_functions:
    - [myToolkit, autoload]

When symfony encounters a new class, it will first try its own autoloading system (and use the locations defined in autoload.yml). If it doesn't find a class definition, it will then try the other autoloading functions from settings.yml, until the class is found. So you can add as many autoloading mechanisms as you want--for instance, to provide a bridge to other framework components (see Chapter 17).

Custom File Structure

Each time the framework uses a path to look for something (from core classes to templates, plug-ins, configurations, and so on), it uses a path variable instead of an actual path. By changing these variables, you can completely alter the directory structure of a symfony project, and adapt to the file organization requirements of any client.

caution

Customizing the directory structure of a symfony project is possible but not necessarily a good idea. One of the strengths of a framework like symfony is that any web developer can look at a project built with it and feel at home, because of the respect for conventions. Make sure you consider this issue before deciding to use your own directory structure.

The Basic File Structure

The path variables are defined in the $sf_symfony_data_dir/config/constants.php file, included when the application bootstraps. These variables are stored in the sfConfig object, and so they are easy to override. Listing 19-3 shows a listing of the path variables and the directory they reference.

Listing 19-3 - Default File Structure Variables, from $sf_symfony_data_dir/config/constants.php

sf_root_dir           # myproject/
                      #   apps/
sf_app_dir            #     myapp/
sf_app_config_dir     #       config/
sf_app_i18n_dir       #       i18n/
sf_app_lib_dir        #       lib/
sf_app_module_dir     #       modules/
sf_app_template_dir   #       templates/
sf_bin_dir            #   batch/
                      #   cache/
sf_base_cache_dir     #     myapp/
sf_cache_dir          #       prod/
sf_template_cache_dir #         templates/
sf_i18n_cache_dir     #         i18n/
sf_config_cache_dir   #         config/
sf_test_cache_dir     #         test/
sf_module_cache_dir   #         modules/
sf_config_dir         #   config/
sf_data_dir           #   data/
sf_doc_dir            #   doc/
sf_lib_dir            #   lib/
sf_model_lib_dir      #     model/
sf_log_dir            #   log/
sf_test_dir           #   test/
sf_plugins_dir        #   plugins/
sf_web_dir            #   web/
sf_upload_dir         #     uploads/

Every path to a key directory is determined by a parameter ending with _dir. Always use the path variables instead of real (relative or absolute) file paths, so that you will be able to change them later, if necessary. For instance, when you want to move a file to the uploads/ directory in an application, you should use sfConfig::get('sf_upload_dir') for the path instead of SF_ROOT_DIR.'/web/uploads/'.

The module directory structure is defined at runtime, when the routing system determines the module name ($module_name). It is automatically built according to the path names defined in the constants.php file, as shown in Listing 19-4.

Listing 19-4 - Default Module File Structure Variables

sf_app_module_dir                 # modules/
module_name                       #  mymodule/
sf_app_module_action_dir_name     #    actions/
sf_app_module_template_dir_name   #    templates/
sf_app_module_lib_dir_name        #    lib/
sf_app_module_view_dir_name       #    views/
sf_app_module_validate_dir_name   #    validate/
sf_app_module_config_dir_name     #    config/
sf_app_module_i18n_dir_name       #    i18n/

So, for instance, the path to the validate/ directory of the current module is built dynamically at runtime:

sfConfig::get('sf_app_module_dir').'/'.$module_name.'/'.sfConfig::get('sf_app_module_validate_dir_name')

Customizing the File Structure

You will probably need to modify the default project file structure if you develop an application for a client who already has a defined directory structure and who is not willing to change it to comply with the symfony logic. By overriding the sf_XXX_dir and sf_XXX_dir_name variables with sfConfig, you can make symfony work for a totally different directory structure than the default structure. The best place to do this is in the application config.php file.

caution

Use the application config.php and not the project one to override the sf_XXX_dir and sf_XXX_dir_name variables with sfConfig. The project config/config.php file is loaded very early in the life of a request, at a time when the sfConfig class doesn't exist yet, and when the constants.php file is not yet loaded.

For instance, if you want all applications to share a common directory for the template layouts, add this line to the myapp/config/config.php file to override the sf_app_template_dir settings:

sfConfig::set('sf_app_template_dir', sfConfig::get('sf_root_dir').DIRECTORY_SEPARATOR.'templates');

Note that the application config.php file is not empty, so if you need to include file structure definitions there, do it at the end of the file.

Modifying the Project Web Root

All the paths built in constants.php rely on the project root directory, which is a constant defined in the front controller (SF_ROOT_DIR). Usually, the root directory is one level above the web/ directory, but you can use a different structure. Suppose that your main directory structure is made of two directories, one public and one private, as shown in Listing 19-5. This typically happens when hosting a project on a shared host.

Listing 19-5 - Example of Custom Directory Structure for a Shared Host

symfony/    # Private area
  apps/
  batch/
  cache/
  ...
www/        # Public area
  images/
  css/
  js/
  index.php

In this case, the root directory is the symfony/ directory. So the index.php front controller simply needs to define the SF_ROOT_DIR as follows for the application to work:

define('SF_ROOT_DIR', dirname(__FILE__).'/../symfony');

In addition, since the public area is www/ instead of the usual web/, you must override two file paths in the application config.php file, as follows:

sfConfig::add(array(
  'sf_web_dir'      => SF_ROOT_DIR.'/../www',
  'sf_upload_dir'   => SF_ROOT_DIR.'/../www/'.sfConfig::get('sf_upload_dir_name'),
));

Linking to Symfony Libraries

The paths to the framework files are defined in the project config.php file, as you can see in Listing 19-6.

Listing 19-6 - The Paths to the Framework Files, in myproject/config/config.php

<?php
 
// symfony directories
$sf_symfony_lib_dir  = '/path/to/symfony/lib';
$sf_symfony_data_dir = '/path/to/symfony/data';

These paths are initialized when you call a symfony init-project from the command line, and refer to the symfony installation used to build the project. They are used both by the command line and by the MVC architecture.

This means that you can switch to another installation of symfony by changing the paths to the framework files.

These paths should be absolute, but by using dirname(__FILE__), you can refer to files inside the project structure and preserve independence of the chosen directory for the project installation. For instance, many projects choose to have the symfony lib/ directory appear as a symbolic link in the project lib/symfony/ directory, and do the same for the symfony data/ directory, as follows:

myproject/
  lib/
    symfony/ => /path/to/symfony/lib
  data/
    symfony/ => /path/to/symfony/data

In this case, the project config.php file just needs to define the symfony directories as follows:

$sf_symfony_lib_dir  = dirname(__FILE__).'/../lib/symfony';
$sf_symfony_data_dir = dirname(__FILE__).'/../data/symfony';

The same principle also applies if you choose to include the symfony files as a svn:externals in the project lib/vendor/ directory:

myproject/
  lib/
    vendor/
      svn:externals symfony http://svn.symfony-project.com/branches/1.0

In this case, the config.php file should look like this:

$sf_symfony_lib_dir  = dirname(__FILE__).'/../lib/vendor/symfony/lib';
$sf_symfony_data_dir = dirname(__FILE__).'/../lib/vendor/symfony/data';

tip

Sometimes, the different servers running an application don't have the same path to the symfony libraries. One way to enable that is to exclude the project config.php file from the synchronization (by adding it to rsync_exclude.txt). Another method is to keep the same paths in the development and production versions of config.php, but to have these paths point to symbolic links that can vary according to the server.

Understanding Configuration Handlers

Each configuration file has a handler. The job of configuration handlers is to manage the configuration cascade, and to do the translation between the configuration files and the optimized PHP code executable at runtime.

Default Configuration Handlers

The default handler configuration is stored in $sf_symfony_data_dir/config/config_handlers.yml. This file links the handlers to the configuration files according to a file path. Listing 19-7 shows an extract of this file.

Listing 19-7 - Extract of $sf_symfony_data_dir/config/config_handlers.yml

config/settings.yml:
  class:    sfDefineEnvironmentConfigHandler
  param:
    prefix: sf_

config/app.yml:
  class:    sfDefineEnvironmentConfigHandler
  param:
    prefix: app_

config/filters.yml:
  class:    sfFilterConfigHandler

modules/*/config/module.yml:
  class:    sfDefineEnvironmentConfigHandler
  param:
    prefix: mod_
    module: yes

For each configuration file (config_handlers.yml identifies each file by a file path with wildcards), the handler class is specified under the class key.

The settings of configuration files handled by sfDefineEnvironmentConfigHandler can be made available directly in the code via the sfConfig class, and the param key contains a prefix value.

You can add or modify the handlers used to process each configuration file--for instance, to use INI or XML files instead of YAML files.

note

The configuration handler for the config_handlers.yml file is sfRootConfigHandler and, obviously, it cannot be changed.

If you ever need to modify the way the configuration is parsed, create an empty config_handlers.yml file in your application's config/ folder and override the class lines with the classes you wrote.

Adding Your Own Handler

Using a handler to deal with a configuration file provides two important benefits:

  • The configuration file is transformed into executable PHP code, and this code is stored in the cache. This means that the configuration is parsed only once in production, and the performance is optimal.
  • The configuration file can be defined at different levels (project and application) and the final parameter values will result from a cascade. So you can define parameters at a project level and override them on a per-application basis.

If you feel like writing your own configuration handler, follow the example of the structure used by the framework in the $sf_symfony_lib_dir/config/ directory.

Let's suppose that your application contains a myMapAPI class, which provides an interface to a third-party web service delivering maps. This class needs to be initialized with a URL and a user name, as shown in Listing 19-8.

Listing 19-8 - Example of Initialization of the myMapAPI Class

$mapApi = new myMapAPI();
$mapApi->setUrl($url);
$mapApi->setUser($user);

You may want to store these two parameters in a custom configuration file called map.yml, located in the application config/ directory. This configuration file might contain the following:

api:
  url:  map.api.example.com
  user: foobar

In order to transform these settings into code equivalent to Listing 19-8, you must build a configuration handler. Each configuration handler must extend sfConfigHandler and provide an execute() method, which expects an array of file paths to configuration files as a parameter, and must return data to be written in a cache file. Handlers for YAML files should extend the sfYamlConfigHandler class, which provides additional facilities for YAML parsing. For the map.yml file, a typical configuration handler could be written as shown in Listing 19-9.

Listing 19-9 - A Custom Configuration Handler, in myapp/lib/myMapConfigHandler.class.php

<?php
 
class myMapConfigHandler extends sfYamlConfigHandler
{
  public function execute($configFiles)
  {
    $this->initialize();
 
    // Parse the yaml
    $config = $this->parseYamls($configFiles);
 
    $data  = "<?php\n";
    $data .= "\$mapApi = new myMapAPI();\n";
 
    if (isset($config['api']['url'])
    {
      $data .= sprintf("\$mapApi->setUrl('%s');\n", $config['api']['url']);
    }
 
    if (isset($config['api']['user'])
    {
      $data .= sprintf("\$mapApi->setUser('%s');\n", $config['api']['user']);
    }
 
    return $data;
  }
}

The $configFiles array that symfony passes to the execute() method will contain a path to all the map.yml files found in the config/ folders. The parseYamls() method will handle the configuration cascade.

In order to associate this new handler with the map.yml file, you must create a config_handlers.yml configuration file with the following content:

config/map.yml:
  class: myMapConfigHandler

note

The class must either be autoloaded (that's the case here) or defined in the file whose path is written in a file parameter under the param key.

When you need the code based on the map.yml file and generated by the myMapConfigHandler handler in your application, call the following line:

include(sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_config_dir_name').'/map.yml'));

When calling the checkConfig() method, symfony looks for existing map.yml files in the configuration directories and processes them with the handler specified in the config_handlers.yml file, if a map.yml.php does not already exist in the cache or if the map.yml file is more recent than the cache.

tip

If you want to handle environments in a YAML configuration file, the handler can extend the sfDefineEnvironmentConfigHandler class instead of sfYamlConfigHandler. After calling the parseYaml() method to retrieve configuration, you should call the mergeEnvironment() method. You can do it all in one line by calling $config = $this->mergeEnvironment($this->parseYamls ($configFiles));.

sidebar

Using Existing configuration handlers

If you just need to allow users to retrieve values from the code via sfConfig, you can use the sfDefineEnvironmentConfigHandler configuration handler class. For instance, to have the url and user parameters available as sfConfig::get('map_url') and sfConfig::get('map_user'), define your handler as follows:

config/map.yml:
  class: sfDefineEnvironmentConfigHandler
  param:
    prefix: map_

Be careful not to choose a prefix already used by another handler. Existing prefixes are sf_, app_, and mod_.

Controlling PHP Settings

In order to have a PHP environment compatible with the rules and best practices of agile development, symfony checks and overrides a few settings of the php.ini configuration. This is the purpose of the php.yml file. Listing 19-10 shows the default php.yml file.

Listing 19-10 - Default PHP Settings for Symfony, in $sf_symfony_data_dir/config/php.yml

set:
  magic_quotes_runtime:        off
  log_errors:                  on
  arg_separator.output:        |
    &amp;

check:
  zend.ze1_compatibility_mode: off

warn:
  magic_quotes_gpc:            off
  register_globals:            off
  session.auto_start:          off

The main purpose of this file is to check that the PHP configuration is compatible with your application. It is also very useful to check that your development server configuration is as similar as possible to the production server. That's why you should inspect the production server configuration at the beginning of a project, and report its PHP settings in a php.yml file in your project. You can then develop and test with confidence that you will not encounter any compatibility errors once you deploy your project to the production platform.

The variables defined under the set header are modified (despite how they were defined in the server php.ini file). The variables defined under the warn category cannot be modified on the fly, but symfony can run even if they are not properly set. It is just considered bad practice to have these settings set to on, and symfony will log a warning in this case. The variables defined under the check category cannot be modified on the fly either, but they must have a certain value for symfony to run. So, in this case, an exception is raised if the php.ini file is not correct.

The default php.yml file sets log_errors to on so that you can trace errors in symfony projects. It also recommends that the register_globals be set to off to prevent security breaches.

If you don't want symfony to apply these settings, or if you want to run a project with magic_quotes_gpc and register_globals set to on without warning, then create a php.yml file in your application config/ directory, and override the settings you want to change.

Additionally, if your project requires an extension, you can specify it under the extensions category. It expects an array of extension names, as follows:

extensions: [gd, mysql, mbstring]

Summary

The configuration files can heavily modify the way the framework works. Because symfony relies on configuration even for its core features and file loading, it can adapt to many more environments than just the standard dedicated host. This great configurability is one of the main strengths of symfony. Even if it sometimes frightens newcomers, who see in configuration files a lot of conventions to learn, it allows symfony applications to be compatible with a very large number of platforms and environments. Once you become a master of symfony's configuration, no server will ever refuse to run your applications!