Symfony 1.0, la guía definitiva

19.4. Comprendiendo el funcionamiento de los manejadores de configuración

Cada archivo de configuración dispone de su propio manejador. La responsabilidad de los manejadores de configuración consiste en la gestión de la configuración en cascada y la tránsformación de los archivos de configuración en archivos PHP optimizados para ser utilizados durante la ejecución de la aplicación.

19.4.1. Manejadores de configuración por defecto

La configuración de los manejadores por defecto se guarda en el archivo $sf_symfony_data_dir/config/config_handlers.yml. En este archivo se relacionan los manejadores y los archivos de configuración según su ruta. El listado 19-7 muestra un extracto de este archivo.

Listado 19-7 - Extracto de $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

Para cada archivo de configuración (config_handlers.yml identifica cada archivo mediante una ruta que puede hacer uso de comodines) se especifica bajo la clave class la clase del manejador que se debe utilizar.

Las opciones de los archivos de configuración manejados por sfDefineEnvironmentConfigHandler se pueden acceder directamente desde el código de la aplicación mediante la clase sfConfig, utilizando como prefijo el valor indicado en la clave param/prefix.

Se pueden modificar o crear nuevos manejadores para procesar cada archivo de configuración, de forma que por ejemplo se puedan utilizar archivos de tipo INI o XML en vez de archivos YAML.

Nota El manejador del archivo de configuración config_handlers.yml se denomina sfRootConfigHandler y, obviamente, no se puede modificar.

Si se necesita cambiar la forma en la que se procesa la configuración, se crea un archivo vacío llamado config_handlers.yml el el directorio config/ de la aplicación y se redefine el valor de las líneas class por las clases propias que se han creado.

19.4.2. Creando un manejador propio

El uso de manejadores para procesar los archivos de configuración implica 2 grandes ventajas:

  • El archivo de configuración se transforma en código PHP ejecutable y este código se guarda en la cache. Esto significa que en producción, la configuración se procesa una sola vez y el rendimiento es óptimo.
  • El archivo de configuración se puede definir en varios niveles (proyecto y aplicación) y los valores finales de los parámetros dependen de la configuración en cascada. De esta forma se pueden definir parámetros a nivel de proyecto y redefinir su valor en cada aplicación.

Si se quiere crear un manejador propio, se puede seguir como ejemplo la estructura utilizada por el framework en el directorio $sf_symfony_lib_dir/config/.

En el siguiente ejemplo, se supone que la aplicación dispone de una clase llamada myMapAPI, que proporciona una interfaz con un servicio web externo de mapas. Como muestra el listado 19-8, esta clase se debe inicializar con una URL y un nombre de usuario.

Listado 19-8 - Ejemplo de inicialización de la clase myMapAPI

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

Estos 2 parámetros de configuración se pueden guardar en un archivo de configuración específico llamado map.yml y guardado en el directorio config/. El contenido de este archivo de configuración puede ser:

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

Para transformar estas opciones de configuración en un código equivalente al del listado 19-8, se debe crear un manejador de archivos de configuración. Todos los manejadores definidos deben extender la clase sfConfigHandler y deben proporcionar un método llamado execute(), que espera como parámetro un array de rutas a archivos de configuración y que devuelve los datos que se deben escribir en un archivo de la cache. Los manejadores de archivos de tipo YAML deberían extender la clase sfYamlConfigHandler, que proporciona algunas utilidades para el procesamiento de archivos YAML. Para el archivo map.yml anterior, el manejador de configuración más típico sería el que se muestra en el listado 19-9.

Listado 19-9 - Un manejador de configuraciones propio, en miaplicacion/lib/myMapConfigHandler.class.php

<?php

class myMapConfigHandler extends sfYamlConfigHandler
{
  public function execute($configFiles)
  {
    $this->initialize();

    // Procesar el archivo 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;
  }
}

El array $configFiles que pasa Symfony al método execute() contiene una ruta a cada archivo map.yml que se encuentre en los directorios config/. El método parseYamls() se encarga de realizar la configuración en cascada.

Para asociar este nuevo manejador con los archivos de tipo map.yml, se crea un nuevo archivo de configuración config_handlers.yml con el siguiente contenido:

config/map.yml:
  class: myMapConfigHandler

Nota La clase indicada en class debe cargarse de forma automática (como en este caso) o encontrarse en el archivo cuya ruta se indica en el parámetro file bajo la clave param.

Como sucede con muchos otros archivos de configuración de Symfony, también se puede registrar un manejador de configuración directamente desde el código PHP:

sfConfigCache::getInstance()->registerConfigHandler('config/map.yml', myMapConfigHandler, array());

Cuando se necesita el código basado en el archivo map.yml y que ha generado el manejador myMapConfigHandler, se puede ejecutar la siguiente instrucción dentro del código de la aplicación:

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

Cuando se ejecuta el método checkConfig(), Symfony busca todos los archivos map.yml existentes en los directorios de configuración y los procesa con el manejador especificado en el archivo config_handlers.yml si no existe el archivo map.yml.php correspondiente en la cache o si el archivo map.yml es más reciente que el de la cache.

Truco Si se quieren soportar diferentes entornos en un archivo de configuración YAML, su manejador debe extender la clase sfDefineEnvironmentConfigHandler en vez de la clase sfYamlConfigHandler. Después de ejecutar el método parseYaml() para obtener la configuración, se debe ejecutar el método mergeEnvironment(). Este proceso se puede hacer en una sola línea mediante $config = $this->mergeEnvironment($this->parseYamls ($configFiles));.