Cómo dominar y crear nuevos entornos

Cada aplicación es la combinación de código y un conjunto de configuración que dicta la forma en que el código debería funcionar. La configuración puede definir la base de datos a usar, si o no se debe almacenar en caché, o cómo se debe detallar la anotación cronológica de eventos en la bitácora. En Symfony2, la idea de «entornos» es la idea de que el mismo código base se puede ejecutar con varias configuraciones diferentes. Por ejemplo, el entorno dev debería usar la configuración que facilita el desarrollo y lo hace agradable, mientras que el entorno prod debe usar un conjunto de configuración optimizado para velocidad.

Diferentes entornos, diferentes archivos de configuración

Una típica aplicación Symfony2 comienza con tres entornos: dev, prod y test. Como se mencionó anteriormente, cada «entorno» simplemente representa una manera de ejecutar el mismo código base con diferente configuración. No debería ser una sorpresa entonces que cada entorno cargue su propio archivo de configuración individual. Si estás utilizando el formato de configuración YAML, utiliza los siguientes archivos:

  • para el entorno dev: app/config/config_dev.yml
  • para el entorno prod: app/config/config_prod.yml
  • para el entorno test: app/config/config_test.yml

Esto funciona a través de un estándar sencillo que se utiliza por omisión dentro de la clase AppKernel:

// app/AppKernel.php

// ...

class AppKernel extends Kernel
{
    // ...

    public function registerContainerConfiguration(LoaderInterface $loader)
    {
        $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
    }
}

Como puedes ver, cuando se carga Symfony2, utiliza el entorno especificado para determinar qué archivo de configuración cargar. Esto cumple con el objetivo de múltiples entornos en una manera elegante, potente y transparente.

Por supuesto, en realidad, cada entorno difiere un poco de los demás. En general, todos los entornos comparten una gran configuración base común. Abriendo el archivo de configuración «dev», puedes ver cómo se logra esto fácil y transparentemente:

  • YAML
    imports:
        - { resource: config.yml }
    # ...
    
  • XML
    <imports>
        <import resource="config.xml" />
    </imports>
    <!-- ... -->
    
  • PHP
    $loader->import('config.php');
    // ...
    

Para compartir configuración común, el archivo de configuración de cada entorno simplemente importa primero los ajustes más comunes desde un archivo de configuración central (config.yml). El resto del archivo se puede desviar de la configuración predeterminada sustituyendo parámetros individuales. Por ejemplo, de manera predeterminada, la barra de herramientas web_profiler está desactivada. Sin embargo, en el entorno dev, la barra de herramientas se activa modificando el valor predeterminado en el archivo de configuración dev:

  • YAML
    # app/config/config_dev.yml
    imports:
        - { resource: config.yml }
    
    web_profiler:
        toolbar: true
        # ...
    
  • XML
    <!-- app/config/config_dev.xml -->
    <imports>
        <import resource="config.xml" />
    </imports>
    
    <webprofiler:config
        toolbar="true"
        ... />
  • PHP
    // app/config/config_dev.php
    $loader->import('config.php');
    
    $container->loadFromExtension('web_profiler', array(
        'toolbar' => true,
    
        // ...
    ));
    

Ejecutando una aplicación en entornos diferentes

Para ejecutar la aplicación en cada entorno, carga la aplicación usando como controlador frontal o bien app.php (para el entorno prod) o app_dev.php (para el entorno dev):

http://localhost/app.php      -> entorno *prod*
http://localhost/app_dev.php  -> entorno *dev*

Nota

Las URL dadas asumen que tu servidor web está configurado para utilizar el directorio web/ de la aplicación como su raíz. Lee más en Instalando Symfony2.

Si abres uno de estos archivos, rápidamente verás que el entorno utilizado por cada uno se fija explícitamente:

1
2
3
4
5
6
7
8
9
 <?php

 require_once __DIR__.'/../app/bootstrap_cache.php';
 require_once __DIR__.'/../app/AppCache.php';

 use Symfony\Component\HttpFoundation\Request;

 $kernel = new AppCache(new AppKernel('prod', false));
 $kernel->handle(Request::createFromGlobals())->send();

Como puedes ver, la clave prod especifica que este entorno se ejecutará en el entorno de producción. Una aplicación Symfony2 se puede ejecutar en cualquier entorno usando este código y simplemente cambiando la cadena de entorno.

Nota

El entorno test se utiliza al escribir las pruebas funcionales y no es accesible en el navegador directamente a través de un controlador frontal. En otras palabras, a diferencia de los otros entornos, no hay archivo controlador frontal app_test.php.

Creando un nuevo entorno

De forma predeterminada, una aplicación Symfony2 tiene tres entornos que se encargan de la mayoría de los casos. Por supuesto, debido a que un entorno no es más que una cadena que corresponde a un conjunto de configuración, la creación de un nuevo entorno es muy fácil.

Supongamos, por ejemplo, que antes de desplegarla, necesitas medir el rendimiento de tu aplicación. Una forma de medir el rendimiento de la aplicación es usando una configuración cercana a la de producción, pero con el web_profiler de Symfony2 habilitado. Esto permite a Symfony2 registrar información sobre tu aplicación durante la evaluación.

La mejor manera de lograrlo es a través de un nuevo entorno llamado, por ejemplo, benchmark. Comienza creando un nuevo archivo de configuración:

  • YAML
    # app/config/config_benchmark.yml
    imports:
        - { resource: config_prod.yml }
    
    framework:
        profiler: { only_exceptions: false }
    
  • XML
    <!-- app/config/config_benchmark.xml -->
    <imports>
        <import resource="config_prod.xml" />
    </imports>
    
    <framework:config>
        <framework:profiler only-exceptions="false" />
    </framework:config>
    
  • PHP
    // app/config/config_benchmark.php
    $loader->import('config_prod.php')
    
    $container->loadFromExtension('framework', array(
        'profiler' => array('only-exceptions' => false),
    ));
    

Y con esta simple adición, la aplicación ahora es compatible con un nuevo entorno llamado benchmark.

Este nuevo archivo de configuración importa la configuración del entorno prod y la modifica. Esto garantiza que el nuevo entorno es idéntico al entorno prod, a excepción de los cambios echos explícitamente aquí.

Debido a que deseas que este entorno sea accesible a través de un navegador, también debes crear un controlador frontal para el mismo. Copia el archivo web/app.php a web/app_benchmark.php y edita el entorno para que sea benchmark:

<?php

require_once __DIR__.'/../app/bootstrap.php';
require_once __DIR__.'/../app/AppKernel.php';

use Symfony\Component\HttpFoundation\Request;

$kernel = new AppKernel('benchmark', false);
$kernel->handle(Request::createFromGlobals())->send();

El nuevo entorno ahora es accesible a través de:

http://localhost/app_benchmark.php

Nota

Algunos entornos, como el entorno dev, no están destinados a ser visitados en algún servidor empleado para el público en general. Esto se debe a que ciertos entornos, con fines de depuración, pueden dar demasiada información sobre la aplicación o infraestructura subyacente. Para estar seguros de que estos entornos no son accesibles, se suele proteger al controlador frontal de direcciones IP externas a través del siguiente código en la parte superior del controlador:

if (!in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1'))) {
    die('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}

Entornos y el directorio de caché

Symfony2 aprovecha la memorización en caché de muchas maneras: la configuración de la aplicación, la configuración de enrutado, las plantillas Twig y más, se memorizan como objetos PHP en archivos del sistema de archivos.

Por omisión, estos archivos se memorizan principalmente en el directorio app/cache. Sin embargo, cada entorno memoriza su propio conjunto de archivos:

app/cache/dev   --- directorio caché para el entorno *dev*
app/cache/prod  --- directorio caché para el entorno *prod*

A veces, cuando depuramos, puede ser útil inspeccionar un archivo memorizado para entender cómo está funcionando algo. Al hacerlo, recuerda buscar en el directorio del entorno que estás utilizando (comúnmente dev mientras desarrollas y depuras). Aunque puede variar, el directorio app/cache/dev incluye lo siguiente:

  • appDevDebugProjectContainer.php — el «contenedor del servicio» memorizado que representa la configuración de la aplicación en caché;
  • appdevUrlGenerator.php — la clase PHP generada a partir de la configuración de enrutado y usada cuando genera las URL;
  • appdevUrlMatcher.php — la clase PHP usada para emparejar rutas — busca aquí para ver la lógica de las expresiones regulares compiladas utilizadas para concordar las URL entrantes con diferentes rutas;
  • twig/ — este directorio contiene todas las plantillas Twig en caché.

Nota

Fácilmente puedes cambiar la ubicación y nombre del directorio. Para más información lee el artículo Cómo sustituir la estructura de directorios predeterminada de Symfony.

Bifúrcame en GitHub