Symfony 1.2, la guía definitiva

1.2. Conceptos básicos

Antes de empezar con Symfony, deberías conocer algunos conceptos básicos. Puedes saltarte esta sección si conoces el significado de OOP, ORM, RAD, DRY, KISS, TDD, YAML y PEAR.

1.2.1. PHP 5

Symfony está programado en PHP 5 (http://www.php.net/) y está enfocado al desarrollo de aplicaciones web en el mismo lenguaje de programación. Por este motivo, es obligatorio disponer de unos conocimientos avanzados de PHP 5 para sacar el máximo partido al framework. La versión mínima de PHP requerida para ejecutar Symfony es PHP 5.2.

Los programadores que conocen PHP 4 pero que no han trabajado con PHP 5 deberían centrarse en el nuevo modelo orientado a objetos de PHP.

1.2.2. Programación Orientada a Objetos (OOP)

La programación orientada a objetos (OOP, por sus siglas en inglés Object-oriented programming) no va a ser explicada en este capítulo, ya que se necesitaría un libro entero para ello. Como Symfony hace un uso continuo de los mecanismos orientados a objetos disponibles en PHP 5, es un requisito obligatorio el conocer la OOP antes de aprender Symfony.

En la Wikipedia se explica la OOP de la siguiente manera:

La idea de la programación orientada a objetos es que una aplicación se puede considerar como una colección de unidades individuales, llamadas objetos, que interactúan entre sí. Los programas tradicionales pueden considerarse como una colección de funciones o como una lista de instrucciones de programación.

PHP 5 incluye los conceptos de clase, objeto, método, herencia y muchos otros propios de la programación orientada a objetos. Aquellos que no estén familiarizados con estos conceptos, deberían consultar la documentación oficial de PHP disponible en http://www.php.net/manual/es/language.oop5.basic.php.

1.2.3. Métodos mágicos

Uno de los puntos fuertes de los objetos de PHP es la utilización de los "métodos mágicos". Este tipo de métodos permiten redefinir el comportamiento de las clases sin modificar el código externo. Con estos métodos es posible que la sintaxis de PHP sea más concisa y más fácil de extender. Además, estos métodos son fáciles de reconocer ya que sus nombres siempre empiezan con 2 guiones bajos seguidos (__).

Por ejemplo, al mostrar un objeto, PHP busca de forma implícita un método llamado __toString() en ese objeto y que permite comprobar si se ha creado una visualización personalizada para ese objeto:

$miObjeto = new miClase();
echo $miObjeto;

// Se busca el método mágico
echo $miObjeto->__toString();

Symfony utiliza los métodos mágicos de PHP, por lo que deberías conocer su funcionamiento. La documentación oficial de PHP también explica los métodos mágicos (http://www.php.net/manual/es/language.oop5.magic.php)

1.2.4. PEAR (PHP Extension and Application Repository)

PEAR es un "framework y sistema de distribución para componentes PHP reutilizables". PEAR permite descargar, instalar, actualizar y desinstalar scripts de PHP. Si se utiliza un paquete de PEAR, no es necesario decidir donde guardar los scripts, cómo hacer que se puedan utilizar o cómo extender la línea de comandos (CLI).

PEAR es un proyecto creado por la comunidad de usuarios de PHP, está desarrollado con PHP y se incluye en las distribuciones estándar de PHP.

Truco El sitio web de PEAR, http://pear.php.net/, incluye documentación y muchos paquetes agrupados en categorías.

PEAR es el método más profesional para instalar librerías externas en PHP. Symfony aconseja el uso de PEAR para disponer de una instalación única y centralizada que pueda ser utilizada en varios proyectos. Los plugins de Symfony son paquetes de PEAR con una configuración especial. El propio framework Symfony también está disponible como paquete de PEAR.

Afortunadamente, no es necesario conocer la sintaxis de PEAR para utilizar Symfony. Lo único necesario es entender su funcionamiento y tenerlo instalado. Para comprobar si PEAR está instalado en el sistema, se puede escribir lo siguiente en una línea de comandos:

> pear info pear

El comando anterior muestra la versión de PEAR instalada en el sistema.

El proyecto Symfony dispone de su propio repositorio PEAR, también llamado canal. Los canales de PEAR solamente se pueden utilizar a partir de la versión 1.4.0, por lo que es necesario actualizar PEAR si se dispone de una versión anterior. Para actualizar PEAR, se debe ejecutar el siguiente comando:

> pear upgrade PEAR

1.2.5. Mapeo de Objetos a Bases de datos (ORM)

Las bases de datos siguen una estructura relacional. PHP 5 y Symfony por el contrario son orientados a objetos. Por este motivo, para acceder a la base de datos como si fuera orientada a objetos, es necesario una interfaz que traduzca la lógica de los objetos a la lógica relacional. Esta interfaz se denomina "mapeo de objetos a bases de datos" (ORM, de sus siglas en inglés "object-relational mapping").

Un ORM consiste en una serie de objetos que permiten acceder a los datos y que contienen en su interior cierta lógica de negocio.

Una de las ventajas de utilizar estas capas de abstracción de objetos/relacional es que evita utilizar una sintaxis específica de un sistema de bases de datos concreto. Esta capa transforma automáticamente las llamadas a los objetos en consultas SQL optimizadas para el sistema gestor de bases de datos que se está utilizando en cada momento.

De esta forma, es muy sencillo cambiar a otro sistema de bases de datos completamente diferente en mitad del desarrollo de un proyecto. Estas técnicas son útiles por ejemplo cuando se debe desarrollar un prototipo rápido de una aplicación y el cliente aun no ha decidido el sistema de bases de datos que más le conviene. El prototipo se puede realizar utilizando SQLite y después se puede cambiar fácilmente a MySQL, PostgreSQL u Oracle cuando el cliente se haya decidido. El cambio se puede realizar modificando solamente una línea en un archivo de configuración.

La capa de abstracción utilizada encapsula toda la lógica de los datos. El resto de la aplicación no tiene que preocuparse por las consultas SQL y el código SQL que se encarga del acceso a la base de datos es fácil de encontrar. Los desarrolladores especializados en la programación con bases de datos pueden localizar fácilmente el código.

Utilizar objetos en vez de registros y clases en vez de tablas tiene otra ventaja: se pueden definir nuevos métodos de acceso a las tablas. Por ejemplo, si se dispone de una tabla llamada Cliente con 2 campos, Nombre y Apellido, puede que sea necesario acceder directamente al nombre completo (NombreCompleto). Con la programación orientada a objetos, este problema se resuelve añadiendo un nuevo método de acceso a la clase Cliente de la siguiente forma:

public function getNombreCompleto()
{
  return $this->getNombre().' '.$this->getApellido();
}

Todas las funciones comunes de acceso a los datos y toda la lógica de negocio relacionada con los datos se puede mantener dentro de ese tipo de objetos. Por ejemplo, la siguiente clase CarritoCompra almacena los productos (que son objetos). Para obtener el precio total de los productos del carrito y así realizar el pago, se puede añadir un método llamado getTotal() de la siguiente forma:

public function getTotal()
{
  $total = 0;
  foreach ($this->getProductos() as $producto)
  {
    $total += $producto->getPrecio() * $item->getCantidad();
  }
  return $total;
}

Y eso es todo. Imagina cuanto te hubiera costado escribir una consulta SQL que hiciera lo mismo.

Propel, que también es un proyecto de software libre, es una de las mejores capas de abstracción de objetos/relacional disponibles en PHP 5. Propel está completamente integrado en Symfony e incluso es su ORM por defecto, por lo que la mayoría de las manipulaciones de datos realizadas en este libro siguen la sintaxis de Propel. En el libro se describe la utilización de los objetos de Propel, pero se puede encontrar una referencia más completa en el sitio web de Propel (http://propel.phpdb.org/trac/).

Nota A partir de Symfony 1.1, Propel se incluye en el framework en forma de plugin, lo que facilita el cambio a otro ORM. De hecho, si quieres utilizar Doctrine como ORM en tus proyectos, sólo tienes que instalar el plugin sfDoctrinePlugin.

1.2.6. Desarrollo rápido de aplicaciones (RAD)

Durante mucho tiempo, la programación de aplicaciones web fue un tarea tediosa y muy lenta. Siguiendo los ciclos habituales de la ingeniería del software (como los propuestos por el Proceso Racional Unificado o Rational Unified Process) el desarrollo de una aplicación web no puede comenzar hasta que se han establecido por escrito una serie de requisitos, se han creado los diagramas UML Unified Modeling Language) y se ha producido abundante documentación sobre el proyecto. Este modelo se veía favorecido por la baja velocidad de desarrollo, la falta de versatilidad de los lenguajes de programación (antes de ejecutar el programa se debe construir, compilar y reiniciar) y sobre todo por el hecho de que los clientes no estaban dispuestos a adaptarse a otras metodologías.

Hoy en día, las empresas reaccionan más rápidamente y los clientes cambian de opinión constantemente durante el desarrollo de los proyectos. De este modo, los equipos de desarrollo deben adaptarse a esas necesidades y tienen que poder cambiar la estructura de una aplicación de forma rápida. Afortunadamente, el uso de lenguajes de script como Perl y PHP permiten seguir otras estrategias de programación, como RAD (desarrollo rápido de aplicaciones) y el desarrollo ágil de software.

Una de las ideas centrales de esta metodología es que el desarrollo empieza lo antes posible para que el cliente pueda revisar un prototipo que funciona y pueda indicar el camino a seguir. A partir de ahí, la aplicación se desarrolla de forma iterativa, en la que cada nueva versión incorpora nuevas funcionalidades y se desarrolla en un breve espacio de tiempo.

Las consecuencias de estas metodologías para el desarrollador son numerosas. El programador no debe pensar acerca de las versiones futuras al incluir una nueva funcionalidad. Los métodos utilizados deben ser lo más sencillos y directos posibles. Estas ideas se resumen en el principio denominado KISS: ¡Hazlo sencillo, idiota! Keep It Simple, Stupid)

Cuando se modifican los requisitos o cuando se añade una nueva funcionalidad, normalmente se debe reescribir parte del código existente. Este proceso se llama refactorización y sucede a menudo durante el desarrollo de una aplicación web. El código suele moverse a otros lugares en función de su naturaleza. Los bloques de código repetidos se refactorizan en un único lugar, aplicando el principio DRY: No te repitas Don't Repeat Yourself).

Para asegurar que la aplicación sigue funcionando correctamente a pesar de los cambios constantes, se necesita una serie de pruebas unitarias que puedan ser automatizadas. Si están bien escritas, las pruebas unitarias permiten asegurar que nada ha dejado de funcionar después de haber refactorizado parte del código de la aplicación. Algunas metodologías de desarrollo de aplicaciones obligan a escribir las pruebas antes que el propio código, lo que se conoce como TDD: desarrollo basado en pruebas test-driven development).

Nota Existen otros principios y hábitos relacionados con el desarrollo ágil de aplicaciones. Una de las metodologías más efectivas se conoce como XP: programación extrema Extreme Programming). La documentación relacionada con XP puede enseñarte mucho sobre el desarrollo rápido y efectivo de las aplicaciones. Una buena forma de empezar con XP son los libros escritos por Kent Beck en la editorial Addison-Wesley.

Symfony es la herramienta ideal para el RAD. De hecho, el framework ha sido desarrollado por una empresa que aplica el RAD a sus propios proyectos. Por este motivo, aprender a utilizar Symfony no es como aprender un nuevo lenguaje de programación, sino que consite en aprender a tomar las decisiones correctas para desarrollar las aplicaciones de forma más efectiva.

1.2.7. YAML

Según el sitio web oficial de YAML (http://www.yaml.org/), YAML es "un formato para serializar datos que es fácil de procesar por las máquinas, fácil de leer para las personas y fácil de interactuar con los lenguajes de script". Dicho de otra forma, YAML es un lenguaje muy sencillo que permite describir los datos como en XML, pero con una sintaxis mucho más sencilla. YAML es un formato especialmente útil para describir datos que pueden ser transformados en arrays simples y asociativos, como por ejemplo:

$casa = array(
  'familia' => array(
    'apellido'  => 'García',
    'padres'  => array('Antonio', 'María'),
    'hijos'   => array('Jose', 'Manuel', 'Carmen')
  ),
  'direccion' => array(
    'numero'        => 34,
    'calle'         => 'Gran Vía',
    'ciudad'        => 'Cualquiera',
    'codigopostal'  => '12345'
  )
);

Este array de PHP se puede crear directamente procesando esta cadena de texto en formato YAML:

casa:
  familia:
    apellido: García
    padres:
      - Antonio
      - María
    hijos:
      - Jose
      - Manuel
      - Carmen
  direccion:
    numero: 34
    calle: Gran Vía
    ciudad: Cualquiera
    codigopostal: "12345"

YAML utiliza la tabulación para indicar su estructura, los elementos que forman una secuencia utilizan un guión medio y los pares clave/valor de los array asociativos se separan con dos puntos. YAML también dispone de una notación resumida para describir la misma estructura con menos líneas: los arrays simples se definen con [] y los arrays asociativos se definen con {}. Por tanto, los datos YAML anteriores se pueden escribir de forma abreviada de la siguiente manera:

casa:
  familia: { apellido: García, padres: [Antonio, María], hijos: [Jose, Manuel, Carmen] }
  direccion: { numero: 34, direccion: Gran Vía, ciudad: Cualquiera, codigopostal: "12345" }

YAML es el acrónimo de "YAML Ain't Markup Language" ("YAML No es un Lenguaje de Marcado") y se pronuncia "yamel". El formato se lleva utilizando desde 2001 y existen utilidades para procesar YAML en una gran variedad de lenguajes de programación.

Truco La especificación completa del formato YAML se puede encontrar en http://www.yaml.org/.

Como se ha visto, YAML es mucho más rápido de escribir que XML (ya que no hacen falta las etiquetas de cierre y el uso continuo de las comillas) y es mucho más poderoso que los tradicionales archivos .ini (ya que estos últimos no soportan la herencia y las estructuras complejas). Por este motivo, Symfony utiliza el formato YAML como el lenguaje preferido para almacenar su configuración. Este libro contiene muchos archivos YAML, pero como es tan sencillo, probablemente no necesites aprender más detalles de este formato.