Comunidad de diseño web y desarrollo en internet

Introducción a Symfony2

El objetivo este tutorial es ofrecer una visión panorámica del framework PHP para el desarrollo de aplicaciones web Symfony2. El desarrollo de una sencilla aplicación web servirá como elemento vertebrador de este documento.



Contenidos


Debido a la extensión del tutorial lo hemos dividido en tres partes.

Primera parte

En esta primera parte presentamos los aspectos fundamentales y consta de los siguientes apartados:
  • ¿Qué es Symfony2?
  • Instalación y configuración de Symfony2
  • Los Bundles: Plugins de primera clase


Segunda parte

En la segunda parte comenzamos el desarrollo de la aplicación de ejemplo. En esta parte, a medida que se desarrolla la aplicación, se presenta la mayor parte de los conceptos clave del framework. Consta del siguiente apartado:
  • La aplicación gestión de alimentos en Symfony2


Tercera parte

Finalmente en la tercera parte continuaremos con el desarrollo de la aplicación, aunque ahora la densidad de conceptos importantes disminuye, y casi todo se puede hacer aplicando lo que ya se ha estudiado. También se ofrece, como conclusión, una chuleta-resumen de todo lo que se ha visto en el tutorial. Consta de los siguientes apartados:
  • Implementamos el resto de la aplicación
  • El tutorial en chuletas


Para seguir el tutorial necesitarás un entorno con:
  • un servidor web con PHP 5.3.x (x>2)
  • un servidor MySQL 5
  • tu IDE o editor favorito


Descripción de la aplicación

Vamos a construir una aplicación web para elaborar y consultar un repositorio de alimentos con datos acerca de sus propiedades dietéticas. Utilizaremos una base de datos para almacenar dichos datos que consistirá en una sola tabla con la siguiente información sobre alimentos:
  • El nombre del alimento,
  • la energía en kilocalorías ,
  • la cantidad de proteínas,
  • la cantidad hidratos de carbono en gramos
  • la cantidad de fibra en gramos y
  • la cantidad de grasa en gramos,

...todo ello por cada 100 gramos de alimento. Aunque se trata de una aplicación muy sencilla, cuenta con los elementos suficientes para mostrar las características básicas de Symfony2. Utilizando algún cliente MySQL (phpMyAdmin, por ejemplo) crea la siguiente base de datos para almacenar los alimentos e introduce algunos registros para probar la aplicación.

Código :

CREATE TABLE `alimentos` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `nombre` varchar(255) NOT NULL,
      `energia` decimal(10,0) NOT NULL,
      `proteina` decimal(10,0) NOT NULL,
      `hidratocarbono` decimal(10,0) NOT NULL,
      `fibra` decimal(10,0) NOT NULL,
      `grasatotal` decimal(10,0) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;


¡Y ya podemos comenzar el tutorial!

¿Qué es Symfony2?


La respuesta rápida, no por ello menos cierta, es que Symfony2 es un framework PHP para el desarrollo de aplicaciones web. Sin embargo, los creadores de Symfony2 no la darían por buena. Posiblemente tampoco aprobasen completamente lo que voy a decir a continuación (¡son unos programadores, además de excelentes, muy "quisquillosos"!).

El objetivo principal de Symfony2 no es tanto desarrollar otro framework PHP, sino desarrollar un conjunto de componentes estables, independientes, fácilmente acoplables (que no acoplados) para formar sistemas más complejos, mediante los cuales se puedan resolver problemas relacionados con el desarrollo de aplicaciones web en PHP. Obviamente no es necesario utilizar todos los componentes de Symfony2; gracias a su absoluta independencia se pueden utilizar únicamente aquellos que se requieran para resolver el problema en cuestión. Symfony2 se presenta así como una especie de Lego en el mundo del desarrollo en PHP.

Con estos componentes, uno de los problemas que se puede resolver es el de la creación de un framework de desarrollo web. De hecho, uno de los primeros productos que se han construido con estos componentes ha sido el framework de desarrollo conocido como Distribución Standard de Symfony2, o más brevemente Symfony2 sin más. Y es precisamente del estudio de esta distribución de lo que trata este tutorial.

Así pues, el término Symfony2 puede referirse a:
  1. Los componentes de Symfony2
  2. El framework de Symfony2, conocido como distribución standard de Symfony2.


En el momento en que se escribe este texto, lo más probable es que se trate de lo segundo.

Los componentes de Symfony2, se están utilizando para otros proyectos (Drupal 8 es un buen ejemplo), y su uso aumentará cuando dispongan de una documentación tan exhaustiva y bien elaborada como la que cuenta en estos momentos el framework Symfony2.

En este enlace encontrarás una relación de todos los componentes de Symfony2 y su documentación.

Los componentes son las "tripas" del monstruo Symfony2. No hablaremos mucho más acerca de estos componentes a lo largo del tutorial. Pero debes saber que existen. Puede que te ayuden a resolver tu próximo proyecto, y muy probablemente sean los ladrillos fundamentales con los que se construyan muchas de las aplicaciones PHP en un futuro no muy lejano.

Instalación y configuración de Symfony2


A partir de este momento, y mientras no lo especifiquemos explícitamente, cuando hablemos de Symfony2 nos estamos refiriendo al framework, concretamente a la edición estándard.

En este apartado vamos a instalar y configurar Symfony2, y lo dejaremos listo para construir la aplicación de gestión de alimentos sobre él.

Bájate de http://symfony.com/download la última versión de la rama 2.0 de Symfony2. Verás que hay una modalidad normal y otra without vendors. Utiliza la primera.

La modalidad normal contiene todas las librerías de terceros (vendors) necesarias para comenzar a trabajar con el framework, mientras que la modalidad without vendors, como su nombre indica, viene sin estas librerías, razón por lo que hay que instalarlas posteriormente mediante una herramienta incluida con Symfony2 (bin/vendors) que utiliza el sistema de control de versiones git para bajar las últimas versiones desde el repositorio de github, donde se encuentra todo el código de Symfony2.


Descomprime el archivo descargado en algún directorio accesible al servidor web, esto es, dentro de su Document root. Para que la aplicación funcione, el servidor web debe poder escribir en los directorios app/cache y app/logs. Si estás utilizando un sistema operativo tipo UNIX (Ubuntu, MacOSX, etcétera), la forma más fácil de dar dichos permisos es:

Código :

chmod -R 777 app/cache app/logs


Durante toda el tutorial suponemos que has hecho esta operación directamente en el Document root del servidor web, de manera que tendrá la siguiente estructura de directorios:

Código :

 /var/www/    (o donde tengas mapeado tu Document root)
        |
        └── Symfony
       |
       ├── LICENSE
       ├── README.md
       ├── app/
       ├── bin/
       ├── deps
       ├── deps.lock
       ├── src/
       ├── vendor/
       └── web/


Y que tanto el servidor web como el servidor de MySQL están instalado en la máquina local.


A continuación comprobamos que nuestro sistema cumple los requisitos mínimos ejecutando por la interfaz de comandos la siguiente orden:

Código :

php app/check.php


Si el resultado nos señala algún error, debemos resolverlo antes de continuar. Una vez que pasemos al menos los requisitos obligatorios (mandatory requirements), podemos ejecutar la demo que viene incorporada en la distribución standard de Symfony2. Para ello apunta con tu navegador a la siguiente URL:

Código :

 http://localhost/Symfony/web/app_dev.php


¡Y juega un poquito!, Por ejemplo, pica en Run the demo y navega por los distintos enlaces. Fíjate en la pinta que tienen las URL's. La demo muestra el código que genera las páginas de la propia demo. Fíjate en él detenidamente. Verás que muestra dos partes: el del controlador y el de la plantilla (template). Es decir, dos elementos del patrón de diseño MVC (Modelo - Vista - Controlador).

Ya has visto en acción la primera aplicación construida con Symfony2. Ahora vamos a describir la manera en que Symfony2 organiza el código.

Symfony2 organiza los archivos en dos grupos: los que deben estar directamente accesibles al servidor web (CSS's, Javascript, imágenes y el controlador frontal) y los que pueden ser incluidos desde el controlador frontal (librerías PHP y ficheros de configuración). Los primeros viven en el directorio web, y los segundos, según su funcionalidad, están repartidos entre los directorios app , src y vendor.

En una instalación en un entorno de producción, el Document root del servidor web (o del Virtual host dedicado para la aplicación), debe coincidir con el directorio web, y el resto de directorios deben ubicarse fuera del Document root. No obstante, en un entorno de desarrollo podemos relajarnos y, para no andar afinando las configuraciones del servidor web, se puede ubicar todo el código dentro del Document root.

Para paliar el efecto de posibles despistes o malas prácticas por desconocimiento, pereza y otras fatales causas, los directorios src y app, contienen un fichero .htacces que indica al servidor web que no debe mostrar su contenido.


Veamos ahora para qué se utiliza cada uno de estos directorios.


El directorio web

Poco hay que decir ya de este directorio, aquí encontraremos el controlador frontal y todos los assets de la aplicación: CSS's, Javascripts, imágenes, etcétera.

Esta es la estructura del directorio:

Código :

 web
   ├── app_dev.php
   ├── apple-touch-icon.png
   ├── app.php
   ├── bundles
   │   ├── acmedemo
   │   ├── framework
   │   ├── sensiodistribution
   │   └── webprofiler
   ├── config.php
   ├── favicon.ico
   └── robots.txt


Podemos ver 3 scripts PHP:
  • config.php es un script que asiste en la configuración del framework. No es imprescindible. De hecho cuando uno se siente confortable con Symfony2, es más sencillo realizar la configuración directamente sobre el código fuente. Pero para empezar puede servir de ayuda. Si lo utilizas ten en cuenta los permisos de los ficheros del directorio app/config, pues este script debe poder escribir allí.
  • app.php es el controlador frontal de la aplicación, es decir, es el script PHP por el que pasan todas las peticiones. Este script decide el flujo que debe seguir la aplicación "observando" los parámetros que se hayan pasado en cada petición (request). Un conjunto de parámetros determinado se denomina ruta. Veamos un ejemplo para aclararlo: en

    Código :

     http://tu.servidor.web/app.php/articulo/1
    app.php, es el controlador frontal y articulo/1 es una ruta de la aplicación.

  • app_dev.php también es el controlador frontal de la aplicación. ¿Cómo? ¿dos controladores frontales? ¡Eso no parece encajar con lo que acabamos de decir! Bueno tranquilos, tiene su explicación. Se trata de lo que se denomina en Symfony2 el controlador frontal de desarrollo. En principio pinta lo mismo que app.php, pero le añade una barra de depuración que ofrece muchísima información sobre todo lo relacionado con la ejecución del script. Puedes ver la barra de depuración en la demo que has ejecutado hace un momento. Se encuentra abajo de la página. Explórala un poco, te asombrarás de la cantidad de información que te proporciona. Cuando desarrollamos es muy conveniente utilizar este controlador frontal, pero en producción NUNCA debe utilizarse, pues daríamos a los usuarios de la web información que podría comprometer nuestro sistema.


Por otro lado los assets se ubicarán en el directorio bundles/nombre_bundle, donde nombre_bundle es el nombre del bundle al que pertenece el asset en cuestión. Vale, ¿y que es un bundle?, pues por lo pronto quedate con que "es la unidad funcional de código que utiliza Symfony2". Algo así como una de las piezas del Lego Symfony2. Más adelante, dedicamos una sección para hablar de estos "personajes" con más detalle.

El directorio app

La finalidad de este directorio es alojar a los scripts PHP encargados de los procesos de carga del framework (lo que se conoce como bootstraping) y a todo lo que tenga que ver con la configuración general de la aplicación. Los archivos de este directorio son los encargados de unir y dar cohesión a los distintos componentes del framework.

Son especialmente importantes los ficheros autoload.php y AppKernel.ph, ya que hay que tocarlos cada vez que extendemos el framework con nuevas funcionalidades, es decir cada vez que incorporamos nuevos bundles (vamos poniendo en circulación a esta palabreja que usaremos hasta la saciedad).

En autoload.php se mapean los espacios de nombres contra los directorios en los que residirán las clases pertenecientes a dichos espacios de nombre. De esa manera el proceso de autocarga de clases sabrá donde tiene que buscar las clases cuando se usen dichos espacios, sin necesidad de incluir explícitamente (esto es, usando include o require) los archivos donde se definen las clases.

En AppKernel.php, se declaran los bundles que se utilizarán en la aplicación.

En el directorio config se encuentran los archivos de configuración de la aplicación: config.yml, routing.yml y security.yml.

El sistema de configuración de Symfony2 permite trabajar con distintos entornos de ejecución. Los más típicos son prod, para producción y dev, para desarrollo. Pero se pueden definir tantos entornos como deseemos.

En el controlador frontal se indica qué entorno deseamos utilizar en la ejecución del script. Fíjate en la línea 22 de web/app_dev.php, o en la línea 9 del web/app.php:

Código :

 ...
   $kernel = new AppKernel('prod', false);
  ...


El primer argumento decide el entorno de ejecución que se utilizará. ¿Y para que sirve esto? Symfony2 utiliza este dato para saber qué ficheros de configuración debe cargar. Supongamos, por ejemplo, que se especifica dev como entorno de ejecución. Entonces, si existe el fichero config_dev.yml lo cargará, y si no es así cargará config.yml. Lo mismo ocurre con los ficheros routing.yml, security.yml y services.yml. Más adelante estudiaremos para qué sirve cada uno de ellos. Por lo pronto nos conformaremos con saber la dinámica de funcionamiento.

Los entornos proporcionan mucha flexibilidad a la hora de desarrollar una aplicación. Vamos a ilustrar con un ejemplo esta flexibilidad. Un caso que nos encontramos habitualmente es que la aplicación que estamos construyendo debe enviar e-mails. Es bastante molesto tener que disponer de cuentas reales y gestionarlas para que podamos probar la aplicación mientras desarrollamos. Podemos utilizar este sistema de configuración para indicar al framework que en el entorno de desarrollo se envíen todos los e-mails a una sola cuenta, o incluso que no se envíen. Otro ejemplo típico podría ser el definir unos parámetros de conexión a la base de datos para el entorno de producción y otro para el de desarrollo.

Una estrategia muy adecuada para tratar con los ficheros de configuración cuando queremos que haya partes comunes y partes diferentes en cada entorno, es definir todos los parámetros comunes en el fichero fichconfig.yml (donde fichconfig es config, security, routing o services), y los particulares de cada entorno en el fichero fichconfig_env.yml (donde env es dev, prod o cualquier otro nombre de entorno que usemos). Por último importamos los primeros (comunes) desde los últimos (particulares) de la siguiente manera:

Inicio del fichero fichconfig_env.yml

Código :

 imports:
    - { resource: fichconfig.yml }
    ...


Puedes comprobar que esta es la estrategia utilizada por la distribución standard de Symfony2 con los ficheros config.yml, config_dev.yml y config_prod.yml.

Para acelerar la ejecución de los scripts, la configuración, el enrutamiento y las plantillas de twig son compiladas y almacenadas en el directorio cache. Por otro lado, los errores y otra información de interés acerca de eventos que ocurren cuando se ejecuta el framework, son registrados en archivos que se almacenan en el directorio logs. Por eso estos dos directorios deben tener permisos de escritura para el servidor web.

Por último, en este directorio tan "denso", encontramos la navaja suiza de Symfony2, la aplicación app/console. Prueba a ejecutarla sin pasarle ningún argumento. Verás una lista con todas las tareas que se pueden lanzar por línea de comandos.

Código :

 php app/console



El directorio vendor

Aquí se aloja todo el código funcional que no es tuyo. Es lo que tradicionalmente se conoce como librerías de terceros. Entre otras cosas, el directorio contiene los componentes de Symfony2, el ORM Doctrine2 y el sistema de plantillas twig. Cuando amplíes tu aplicación con nuevos bundles de terceros instalados automáticamente con la aplicación bin/vendors, será aquí donde se ubique el código.

El directorio src

Es el directorio donde colocarás tu código. Más concretamente: tus bundles. A base de utilizar este palabro acabarás por asimilarlo antes que te lo expliquemos :-).

El directorio bin

El nombre de este directorio es un clásico en el mundo UNIX. En él se colocan archivos ejecutables. La distribución standard solo trae el ejecutable vendors que se utiliza, en combinación con el fichero deps (dependencias), para
instalar componentes de terceros (vendors).

Y con esto acabamos la descripción de los directorios de Symfony2. Ha llegado el momento de hablar de los bundles, esos grandes desconocidos (¡por ahora!).

Los Bundles: Plugins de primera clase

Si los creadores de Symfony2 hubieran elegido la palabra plugin en lugar de bundle, es probable que te hubieses hecho una idea más concreta de lo que es un bundle. Pues bien, por lo pronto, piensa que un bundle es un plugin, por que no es ni más ni menos que eso.

Cualquier framework que se precie debe ofrecer un mecanismo de extensión que permita ampliar la aplicación sin compromenter la escalabilidad. Para ello las piezas que se añaden al sistema deben ser bloques prácticamente autónomos y con una interfaz sencilla para engancharlos (to plug, en inglés) al sistema. A estos bloques se les conoce a lo largo y ancho de la galaxia con el nombre de plugin (o complemento, en castellano). ¿Por qué los creadores de Symfony2 han decidido llamarles bundles en su lugar? Lo mismo hay alguna razón teórica que se me escapa. Pero de lo que sí estoy seguro es que hay una razón histórica:

El antecesor de Symfony2, el fantástico symfony 1.x organiza el código en aplicaciones, que a su vez están formadas por módulos con la implementación de las acciones. Además ofrece un mecanismo de extensión basado en plugins, los cuales también organizan el código en módulos con sus acciones. Pero a pesar de este paralelismo las aplicaciones son "más importantes" que los plugins. De hecho, las aplicaciones pueden usar módulos de los plugins, pero lo contrario no tiene sentido tal y como está organizado symfony 1.x. Con el tiempo los desarrolladores se dieron cuenta de que era más fácil de mantener y organizar los plugins, ya que son bloques de código autónomos y fácilmente acoplables a la aplicación. Este hecho llevó de forma natural a reorganizar la aplicación colocando todo el código funcional en los plugins. Las aplicaciones se quedaban prácticamente vacías de código y tan solo contenían ficheros de configuración.

Así pues, en Symfony2 decidieron olvidarse del concepto de aplicación (en el sentido de symfony 1.x), y obligar a que todo el código funcional se organizase en plugins. Es como hacer a los plugins ciudadanos de primera clase del framework. Finalmente, para evitar cualquier confusión y dirimir la diferencia entre plugin y aplicación, decidieron usar la palabra bundle. Y eso es todo.

Si no conoces symfony 1.x, seguro que hubieras preferido llamarle plugin. Y si lo conoces es probable que también.

En fin, lo que realmente debes saber:

:

Un bundle no es más que un directorio que aloja todo aquello relativo a una funcionalidad determinada. Puede incluir clases PHP, plantillas, configuraciones, CSS's y Javascript.


Con esto ponemos fin a la primera parte de este tutorial. En la segunda parte comenzaremos a desarrollar la aplicación de ejemplo que nos servirá para presentar los conceptos claves del framework.

Este trabajo, por Juan David Rodríguez García<juanda at ite.educacion.es>, se encuentra bajo una Licencia Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 Unported.

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate