Cada vez que el framework requiere de una ruta para buscar algo (las clases internas de Symfony, las plantillas, los plugins, los archivos de configuración, etc.) utiliza una variable que almacena la ruta. Modificando el valor de estas variables, se puede modificar por completo la estructura de directorios de un proyecto Symfony, para adaptarla a las necesidades específicas de cualquier cliente.
Truco Aunque es posible modificar por completo la estructura de directorios de los proyectos Symfony, no se recomienda hacerlo. Uno de los puntos fuertes de los frameworks como Symfony es que cualquier programador puede comprender fácilmente cualquier proyecto desarrollado con Symfony, debido al uso de las convenciones. Por tanto, debe considerarse seriamente las ventajas y desventajas de modificar la estructura de directorios antes de hacerlo.
19.3.1. La estructura de archivos básica
Las variables que almacenan las rutas utilizadas se encuentran en el archivo $sf_symfony_data_dir/config/constants.php
, que se incluye cuando se inicia la aplicación. Todas estas variables se almacenan en el objeto sfConfig
, por lo que es muy fácil redefinir sus valores. El listado 19-3 muestra las variables que almacenan las rutas y el directorio al que hacen referencia.
Listado 19-3 - Variables de la estructura de archivos por defecto, en $sf_symfony_data_dir/config/constants.php
sf_root_dir # miproyecto/
# apps/
sf_app_dir # miaplicacion/
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 # miaplicacion/
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/
Todas las rutas a los directorios principales de Symfony se obtienen a través de opciones acabadas en _dir
. Siempre se deberían utilizar las variables en vez de las rutas reales (absolutas o relativas), de forma que se puedan modificar posteriormente si es necesario. Si se quiere por ejemplo mover un archivo al directorio uploads/
de la aplicación, se debería utilizar como ruta el valor sfConfig::get('sf_upload_dir')
en vez de SF_ROOT_DIR.'/web/uploads/
'.
La estructura de directorios de los módulos se define durante la ejecución de la aplicación, cuando el sistema de enrutamiento determina el nombre del módulo ($module_name
). La estructura de directorios se construye automáticamente en función de las rutas definidas en el archivo constants.php
, como se muestra en el listado 19-4.
Listado 19-4 - Default Module File Structure Variables
sf_app_module_dir # modules/
module_name # mimodelo/
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/
De esta forma, la ruta por ejemplo al directorio validate/
del módulo actual se construye de forma dinámica durante la ejecución de la aplicación de la siguiente forma:
sfConfig::get('sf_app_module_dir').'/'.$module_name.'/'.sfConfig::get('sf_app_module_validate_dir_name')
19.3.2. Modificando la estructura de archivos
Si se desarrolla una aplicación para un cliente que ya dispone de una estructura de directorios definida y que no quiere cambiarla para adaptarse a Symfony, será necesario modificar la estructura de archivos por defecto. Redefiniendo el valor de las variables sf_XXX_dir
y sf_XXX_dir_name
mediante sfConfig
, se puede conseguir que Symfony funcione correctamente con una estructura de directorios completamente diferente a la de por defecto. El mejor archivo para modificar estas variables es el archivo config.php
de la aplicación.
Advertencia Para redefinir las variables sf_XXX_dir
y sf_XXX_dir_name
mediante sfConfig
, se debería utilizar el archivo config.php
de la aplicación y no el del proyecto. El archivo config/config.php
del proyecto se carga muy al principio de cada petición, cuando la clase sfConfig
todavía no está disponible y por tanto, cuando el archivo constants.php
no se ha cargado todavía.
Si por ejemplo se necesita que todas las aplicaciones compartan un directorio común para los layouts de las plantillas, se añade la siguiente línea en el archivo miaplicacion/config/config.php
para redefinir la opción sf_app_template_dir
:
sfConfig::set('sf_app_template_dir', sfConfig::get('sf_root_dir').DIRECTORY_SEPARATOR.'templates');
El archivo config.php
de la aplicación no está vacío, por lo que si se necesitan incluir las definiciones de la estructura de archivos, se deben añadir al final del archivo.
19.3.3. Modificando el directorio raíz del proyecto
Todas las rutas construidas en constants.php
se basan en el directorio raíz del proyecto, que es una constante que se define en el controlador frontal (SF_ROOT_DIR
). Normalmente, el directorio raíz se encuentra un nivel por encima del directorio web/
, pero se puede utilizar una estructura diferente. Si se utiliza una estructura principal de directorios formada por 2 directorios, uno puede ser el directorio público y otro el privado, tal y como muestra el listado 19-5. Esta estructura es muy típica cuando se utiliza un servicio de hosting compartido.
Listado 19-5 - Ejemplo de estructura de directorios propia en un hosting compartido
symfony/ # Area privada apps/ batch/ cache/ ... www/ # Area pública images/ css/ js/ index.php
En este caso, el directorio raíz sería el directorio symfony/
. De esta forma, para que la aplicación funcione correctamente, en el controlador frontal (archivo index.php
) se debe definir la variable SF_ROOT_DIR
de la siguiente forma:
define('SF_ROOT_DIR', dirname(__FILE__).'/../symfony');
Además, como el área pública es www/
en vez del tradicional web/
, se debe redefinir el valor de las rutas a 2 archivos en el archivo de configuración config.php
de la aplicación:
sfConfig::add(array(
'sf_web_dir' => SF_ROOT_DIR.'/../www',
'sf_upload_dir' => SF_ROOT_DIR.'/../www/'.sfConfig::get('sf_upload_dir_name'),
));
19.3.4. Enlazando las librerías de Symfony
Como se ve en el listado 19-6, el archivo config.php
también define las rutas a los archivos del framework.
Listado 19-6 - Las rutas a los archivos del framework, en miproyecto/config/config.php
<?php
// Directorios de Symfony
$sf_symfony_lib_dir = '/ruta/a/symfony/lib';
$sf_symfony_data_dir = '/ruta/a/symfony/data';
Estas rutas se inicializan cuando se ejecuta la tarea symfony init-project
desde la línea de comandos y hacen referencia a la instalación de Symfony que se ha utilizado para construir el proyecto. Las dos rutas se utilizan tanto en la línea de comandos como en la arquitectura MVC.
Por tanto, se puede utilizar otra instalación de Symfony simplemente modificando las rutas a los archivos de Symfony.
Aunque estas rutas pueden ser absolutas, también es posible utilizar dirname(__FILE__)
para hacer referencia a archivos dentro de la estructura del proyecto y para mantener la independencia respecto al directorio elegido para instalar el proyecto. Muchos proyectos prefieren por ejemplo que el directorio lib/
de Symfony aparezca como un enlace simbólico en el directorio lib/symfony/
del proyecto, al igual que el directorio data/
:
miproyecto/ lib/ symfony/ => /ruta/a/symfony/lib data/ symfony/ => /ruta/a/symfony/data
En este caso, en el archivo config.php
del proyecto se deben definir los directorios de Symfony de la siguiente manera:
$sf_symfony_lib_dir = dirname(__FILE__).'/../lib/symfony';
$sf_symfony_data_dir = dirname(__FILE__).'/../data/symfony';
El mismo principio se aplica si se quieren incluir los archivos de Symfony como svn:externals
en el directorio lib/vendor/
del proyecto:
miproyecto/ lib/ vendor/ svn:externals symfony http://svn.symfony-project.com/branches/1.0
En este caso, el archivo config.php
debería ser:
$sf_symfony_lib_dir = dirname(__FILE__).'/../lib/vendor/symfony/lib';
$sf_symfony_data_dir = dirname(__FILE__).'/../lib/vendor/symfony/data';
Truco En ocasiones, los diferentes servidores que ejecutan las aplicaciones no tienen las librerías de Symfony en las mismas rutas. Una forma de conseguirlo es excluir el archivo config.php
del proceso de sincronización (añadiéndolo a la lista del archivo rsync_exclude.txt
). Otra forma de hacerlo es mantener las mismas rutas en la versión de desarrollo y en la de producción del archivo config.php
y que las rutas apunten a enlaces simbólicos que cambian en cada servidor.