Symfony 1.1, la guía definitiva

2.2. Organización del código

Ahora que ya conoces los componentes que forman una aplicación de Symfony, a lo mejor te estás preguntando sobre cómo están organizados. Symfony organiza el código fuente en una estructura de tipo proyecto y almacena los archivos del proyecto en una estructura estandarizada de tipo árbol.

2.2.1. Estructura del proyecto: Aplicaciones, Módulos y Acciones

Symfony considera un proyecto como "un conjunto de servicios y operaciones disponibles bajo un determinado nombre de dominio y que comparten el mismo modelo de objetos".

Dentro de un proyecto, las operaciones se agrupan de forma lógica en aplicaciones. Normalmente, una aplicación se ejecuta de forma independiente respecto de otras aplicaciones del mismo proyecto. Lo habitual es que un proyecto contenga dos aplicaciones: una para la parte pública y otra para la parte de gestión, compartiendo ambas la misma base de datos. También es posible definir proyectos que estén formados por varios sitios web pequeños, cada uno de ellos considerado como una aplicación. En este caso, es importante tener en cuenta que los enlaces entre aplicaciones se deben indicar de forma absoluta.

Cada aplicación está formada por uno o más módulos. Un módulo normalmente representa a una página web o a un grupo de páginas con un propósito relacionado. Por ejemplo, una aplicación podría tener módulos como home, articulos, ayuda, carritoCompra, cuenta, etc.

Los módulos almacenan las acciones, que representan cada una de las operaciones que se puede realizar en un módulo. Por ejemplo el módulo carritoCompra puede definir acciones como anadir, mostrar y actualizar. Normalmente las acciones se describen mediante verbos. Trabajar con acciones es muy similar a trabajar con las páginas de una aplicación web tradicional, aunque en este caso dos acciones diferentes pueden acabar mostrando la misma página (como por ejemplo la acción de añadir un comentario a una entrada de un blog, que acaba volviendo a mostrar la página de la entrada con el nuevo comentario).

Nota Nota del traductor En el párrafo anterior, la acción del carrito se llama anadir y no añadir, ya que el nombre de una acción también se utiliza como parte del nombre de un fichero y como parte del nombre de una función, por lo que se recomienda utilizar exclusivamente caracteres ASCII, y por tanto, no debería utilizarse la letra ñ.

Truco Si crees que todo esto es demasiado complicado para tu primer proyecto con Symfony, puedes agrupar todas las acciones en un único módulo, para simplificar la estructura de archivos. Cuando la aplicación se complique, puedes reorganizar las acciones en diferentes módulos. Como se comenta en el capítulo 1, la acción de reescribir el código para mejorar su estructura o hacerlo más sencillo (manteniendo siempre su comportamiento original) se llama refactorización, y es algo muy común cuando se aplican los principios del RAD "desarrollo rápido de aplicaciones").

La figura 2-3 muestra un ejemplo de organización del código para un proyecto de un blog, siguiendo la estructura de proyecto / aplicación / módulo / acción. No obstante, la estructura de directorios real del proyecto es diferente al esquema mostrado por esa figura.

Ejemplo de organización del código

Figura 2.3 Ejemplo de organización del código

2.2.2. Estructura del árbol de archivos

Normalmente, todos los proyectos web comparten el mismo tipo de contenidos, como por ejemplo:

  • Una base de datos, como MySQL o PostgreSQL
  • Archivo estáticos (HTML, imágenes, archivos de JavaScript, hojas de estilos, etc.)
  • Archivos subidos al sitio web por parte de los usuarios o los administradores
  • Clases y librerías PHP
  • Librerías externas (scripts desarrollados por terceros)
  • Archivos que se ejecutan por lotes batch files) que normalmente son scripts que se ejecutan vía línea de comandos o mediante cron
  • Archivos de log (las trazas que generan las aplicaciones y/o el servidor)
  • Archivos de configuración

Symfony proporciona una estructura en forma de árbol de archivos para organizar de forma lógica todos esos contenidos, además de ser consistente con la arquitectura MVC utilizada y con la agrupación proyecto / aplicación / módulo. Cada vez que se crea un nuevo proyecto, aplicación o módulo, se genera de forma automática la parte correspondiente de esa estructura. Además, la estructura se puede personalizar completamente, para reorganizar los archivos y directorios o para cumplir con las exigencias de organización de un cliente.

2.2.2.1. Estructura de la raíz del proyecto

La raíz de cualquier proyecto Symfony contiene los siguientes directorios:

apps/
  frontend/
  backend/
cache/
config/
data/
  sql/
doc/
lib/
  model/
log/
plugins/
test/
  bootstrap/
  unit/
  functional/
web/
  css/
  images/
  js/
  uploads/

La tabla 2-1 describe los contenidos de estos directorios

Tabla 2-1. Directorios en la raíz de los proyectos Symfony

Directorio Descripción
apps/ Contiene un directorio por cada aplicación del proyecto (normalmente, frontend y backend para la parte pública y la parte de gestión respectivamente)
cache/ Contiene la versión cacheada de la configuración y (si está activada) la versión cacheada de las acciones y plantillas del proyecto. El mecanismo de cache (que se explica en el Capítulo 12) utiliza los archivos de este directorio para acelerar la respuesta a las peticiones web. Cada aplicación contiene un subdirectorio que guarda todos los archivos PHP y HTML preprocesados
config/ Almacena la configuración general del proyecto
data/ En este directorio se almacenan los archivos relacionados con los datos, como por ejemplo el esquema de una base de datos, el archivo que contiene las instrucciones SQL para crear las tablas e incluso un archivo de bases de datos de SQLite
doc/ Contiene la documentación del proyecto, formada por tus propios documentos y por la documentación generada por PHPdoc
lib/ Almacena las clases y librerías externas. Se suele guardar todo el código común a todas las aplicaciones del proyecto. El subdirectorio model/ guarda el modelo de objetos del proyecto (como se describe en el Capítulo 8)
log/ Guarda todos los archivos de log generados por Symfony. También se puede utilizar para guardar los logs del servidor web, de la base de datos o de cualquier otro componente del proyecto. Symfony crea un archivo de log por cada aplicación y por cada entorno (los archivos de log se ven detalladamente en el Capítulo 16)
plugins/ Almacena los plugins instalados en la aplicación (el Capítulo 17 aborda el tema de los plugins)
test/ Contiene las pruebas unitarias y funcionales escritas en PHP y compatibles con el framework de pruebas de Symfony (que se explica en el capítulo 15). Cuando se crea un proyecto, Symfony crea algunos pruebas básicas
web/ La raíz del servidor web. Los únicos archivos accesibles desde Internet son los que se encuentran en este directorio

2.2.2.2. Estructura de cada aplicación

Todas las aplicaciones de Symfony tienen la misma estructura de archivos y directorios:

apps/
  [nombre aplicacion]/
    config/
    i18n/
    lib/
    modules/
    templates/
      layout.php

La tabla 2-2 describe los subdirectorios de una aplicación

Tabla 2-2. Subdirectorios de cada aplicación Symfony

Directorio Descripción
config/ Contiene un montón de archivos de configuración creados con YAML. Aquí se almacena la mayor parte de la configuración de la aplicación, salvo los parámetros propios del framework. También es posible redefinir en este directorio los parámetros por defecto si es necesario. El Capítulo 5 contiene más detalles sobre la configuración de las aplicaciones
i18n/ Contiene todos los archivos utilizados para la internacionalización de la aplicación, sobre todo los archivos que traducen la interfaz (el Capítulo 13 detalla la internacionalización). La internacionalización también se puede realizar con una base de datos, en cuyo caso este directorio no se utilizaría
lib/ Contiene las clases y librerías utilizadas exclusivamente por la aplicación
modules/ Almacena los módulos que definen las características de la aplicación
templates/ Contiene las plantillas globales de la aplicación, es decir, las que utilizan todos los módulos. Por defecto contiene un archivo llamado layout.php, que es el layout principal con el que se muestran las plantillas de los módulos

Nota En las aplicaciones recién creadas, los directorios i18n/, lib/ y modules/ están vacíos.

Las clases de una aplicación no pueden acceder a los métodos o atributos de otras aplicaciones del mismo proyecto. Además, los enlaces entre 2 aplicaciones de un mismo proyecto se deben indicar de forma absoluta. Esta última restricción es importante durante la inicialización del proyecto, que es cuando debes elegir como dividir el proyecto en aplicaciones.

2.2.2.3. Estructura de cada módulo

Cada aplicación contiene uno o más módulos. Cada módulo tiene su propio subdirectorio dentro del directorio modules y el nombre del directorio es el que se elige durante la creación del módulo.

Esta es la estructura de directorios típica de un módulo:

apps/
  [nombre aplicacion]/
    modules/
      [nombre modulo]/
          actions/
            actions.class.php
          config/
          lib/
          templates/
            indexSuccess.php

La tabla 2-3 describe los subirectorios de un módulo.

Tabla 2-3. Subdirectorios de cada módulo

Directorio Descripción
actions/ Normalmente contiene un único archivo llamado actions.class.php y que corresponde a la clase que almacena todas las acciones del módulo. También es posible crear un archivo diferente para cada acción del módulo
config/ Puede contener archivos de configuración adicionales con parámetros exclusivos del módulo
lib/ Almacena las clases y librerías utilizadas exclusivamente por el módulo
templates/ Contiene las plantillas correspondientes a las acciones del módulo. Cuando se crea un nuevo módulo, automáticamente se crea la plantilla llamada indexSuccess.php

Nota En los módulos recién creados, los directorios config/ y lib/ están vacíos.

2.2.2.4. Estructura del sitio web

Existen pocas restricciones sobre la estructura del directorio web, que es el directorio que contiene los archivos que se pueden acceder de forma pública. Si se utilizan algunas convenciones básicas en los nombres de los subdirectorios, se pueden simplificar las plantillas. La siguiente es una estructura típica del directorio web:

web/
  css/
  images/
  js/
  uploads/

Normalmente, los archivos estáticos se organizan según los directorios de la tabla 2-4.

Tabla 2-4. Subdirectorios habituales en la carpeta web

Directorio Descripción
css/ Contiene los archivos de hojas de estilo creados con CSS (archivos con extensión .css
images/ Contiene las imágenes del sitio con formato .jpg, .png o .gif
js/ Contiene los archivos de JavaScript con extensión .js
uploads/ Se pueden almacenar los archivos subidos por los usuarios. Aunque normalmente este directorio contiene imágenes, no se debe confundir con el directorio que almacena las imágenes del sitio (images/). Esta distinción permite sincronizar los servidores de desarrollo y de producción sin afectar a las imágenes subidas por los usuarios

Nota Aunque es muy recomendable mantener la estructura definida por defecto, es posible modificarla para adaptarse a las necesidades específicas de cada proyecto, como por ejemplo los proyectos que se ejecutan en servidores con sus propias estructuras de directorios definidas y con otras políticas para el desarrollo de las aplicaciones. El Capítulo 19 explica en detalle cómo modificar la estructura de directorios definida por Symfony.