Está en la página 1de 128

Curso

Framework Symfony
Basado en The Definitive Guide to Symfony

Versin 0.3 Mayo 2008

Jordi Llonch
jordi@laigu.net

http://creativecommons.org/licenses/by-sa/3.0/

Symfony

Que es Symfony?
Proyecto, aplicacin y mdulo
Herramientas comunes
Instalar Symfony
Introduccin a la creacin de pginas
MVC

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Controlador
Vista
Modelo

Enlaces y sistema de enrutamiento


Generadores

Que es Symfony?

Que es Symfony?
Un framework para construir aplicaciones web
con PHP.
Un enorme conjunto de herramientas y utilidades
que simplifican el desarrollo de las aplicaciones
web.
Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Que es Symfony?

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Emplea el tradicional patrn de diseo MVC:

Proyecto, aplicacin y mdulo

Proyecto, aplicacin y mdulo


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 lgica en aplicaciones.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Normalmente, una aplicacin se ejecuta de forma


independiente respecto de otras aplicaciones del
mismo proyecto.
Lo habitual es que un proyecto contenga dos
aplicaciones:
Parte pblica
Parte de gestin
(ambas compraten la misma base de datos)

Proyecto, aplicacin y mdulo


Cada aplicacin est formada por uno o ms
mdulos.
Un mdulo normalmente representa a una
pgina web o a un grupo de pginas con un
propsito relacionado.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Por ejemplo, una aplicacin podra tener mdulos


como home, articulos, ayuda, carritoCompra, cuenta,
etc.

Los mdulos almacenan las acciones, que


representan cada una de las operaciones que se
puede realizar en un mdulo. Por ejemplo el
mdulo carritoCompra puede definir acciones
como anadir, mostrar y actualizar.
8

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Proyecto, aplicacin y mdulo

Proyecto, aplicacin y mdulo

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Estructura de archivos del proyecto:


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

10

Proyecto, aplicacin y mdulo

Directorios en la raz de los proyectos Symfony:


Directorio

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

apps/

Descripcin
Contiene un directorio por cada aplicacin del proyecto (normalmente, frontend y backend para la parte
pblica y la parte de gestin respectivamente)

batch/

Contiene los scripts de PHP que se ejecutan mediante la lnea de comandos o mediante la programacin
de tareas para realizar procesos en lotes (batch processes)

cache/

Contiene la versin cacheada de la configuracin y (si est activada) la versin cacheada de las acciones y
plantillas del proyecto. El mecanismo de cache utiliza los archivos de este directorio para acelerar la
respuesta a las peticiones web. Cada aplicacin contiene un subdirectorio que guarda todos los archivos
PHP y HTML preprocesados

config/

Almacena la configuracin 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 documentacin del proyecto, formada por tus propios documentos y por la documentacin
generada por PHPdoc

lib/

Almacena las clases y libreras externas. Se suele guardar todo el cdigo comn a todas las aplicaciones
del proyecto. El subdirectorio model/ guarda el modelo de objetos del proyecto

log/

Guarda todos los archivos de log generados por Symfony. Tambin 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 aplicacin y por cada entorno

plugins/

Almacena los plugins instalados en la aplicacin

test/

Contiene las pruebas unitarias y funcionales escritas en PHP y compatibles con el framework de pruebas
de Symfony. Cuando se crea un proyecto, Symfony crea algunos pruebas bsicas

web/

La raz del servidor web. Los nicos archivos accesibles desde Internet son los que se encuentran en este
directorio

11

Proyecto, aplicacin y mdulo

Estructura de cada aplicacin:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Directorio

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

Descripcin

config/

Contiene un montn de archivos de configuracin creados con YAML.


Aqu se almacena la mayor parte de la configuracin de la aplicacin,
salvo los parmetros propios del framework. Tambin es posible
redefinir en este directorio los parmetros por defecto si es necesario.

i18n/

Contiene todos los archivos utilizados para la internacionalizacin de la


aplicacin, sobre todo los archivos que traducen la interfaz. La
internacionalizacin tambin se puede realizar con una base de datos,
en cuyo caso este directorio no se utilizara

lib/

Contiene las clases y libreras utilizadas exclusivamente por la


aplicacin

modules/

Almacena los mdulos que definen las caractersticas de la aplicacin

Contiene las plantillas globales de la aplicacin, es decir, las que


utilizan todos los mdulos. Por defecto contiene un archivo llamado
templates/ layout.php, que es el layout principal con el que se muestran las
plantillas de los mdulos

12

Proyecto, aplicacin y mdulo

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Estructura de cada mdulo:

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

Directorio

Descripcin

actions/

Normalmente contiene un nico archivo llamado


actions.class.php y que corresponde a la clase que
almacena todas las acciones del mdulo. Tambin es
posible crear un archivo diferente para cada accin del
mdulo

config/

Puede contener archivos de configuracin adicionales


con parmetros exclusivos del mdulo

lib/

Almacena las clases y libreras utilizadas exclusivamente


por el mdulo

Contiene las plantillas correspondientes a las acciones


del mdulo. Cuando se crea un nuevo mdulo,
templates/ automticamente se crea la plantilla llamada
indexSuccess.php
validate/

Contiene archivos de configuracin relacionados con la


validacin de formularios

13

Proyecto, aplicacin y mdulo

Estructura del sitio web:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

web/
css/
images/
js/
uploads/

Directorio

Descripcin

css/

Contiene los archivos de hojas de estilo creados con CSS (archivos


con extensin .css

images/

Contiene las imgenes del sitio con formato .jpg, .png o .gif

js/

Contiene los archivos de JavaScript con extensin .js

uploads/

Se almacenan los archivos subidos por los usuarios. Aunque


normalmente este directorio contiene imgenes, no se debe confundir
con el directorio que almacena las imgenes del sitio (images/). Esta
distincin permite sincronizar los servidores de desarrollo y de
produccin sin afectar a las imgenes subidas por los usuarios

14

Herramientas comunes

Herramientas comunes

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

En esta seccin mostraremos tcnicas que se


utilizan una y otra vez en Symfony:

Contenedor de parmetros

Constantes (configuraciones)

Carga automtica de clases

16

Herramientas comunes

Contenedores de parmetros:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Se trata de una forma eficiente de encapsular los


atributos y as poder utilizar mtodos getter y setter
sencillos.
La clase sfResponse por ejemplo incluye un
contenedor de parmetros que se puede obtener
mediante el mtodo getParameterHolder().
$respuesta->getParameterHolder()->set('parametro', 'valor');
echo $respuesta->getParameterHolder()->get('parametro');
=> 'valor'
// Formato abreviado
$respuesta->setParameter('parametro', 'valor');
echo $respuesta->getParameter('parametro');
=> 'valor'
17

Herramientas comunes

Contenedores de parmetros:

Aadir contenedores de parmetros a tus propias


clases:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

class MiClase
{
protected $contenedor_parametros = null;
public function initialize ($parametros = array())
{
$this->contenedor_parametros = new sfParameterHolder();
$this->contenedor_parametros->add($parametros);
}

public function getContenedorParametros()


{
return $this->contenedor_parametros;
}

18

Herramientas comunes

Constantes (configuraciones):

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Symfony no define casi ninguna constante. La razn


es que las constantes tienen el inconveniente de no
poderse modificar su valor una vez definidas.
Por este motivo, Symfony utiliza su propio objeto para
almacenar la configuracin, llamado sfConfig, y que
reemplaza a las constantes.
// En vez de constantes de PHP,
define('MI_CONSTANTE', 'valor');
echo MI_CONSTANTE;
// Symfony utiliza el objeto sfConfig
sfConfig::set('mi_constante', 'valor');
echo sfConfig::get('mi_constante');

19

Herramientas comunes

Carga automtica de clases:

Normalmente, cuando se utiliza un mtodo de una


clase o cuando se crea un objeto en PHP, se debe
incluir antes la definicin de esa clase.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

include 'clases/MiClase.php';
$miObjeto = new MiClase();

En los proyectos complejos con muchas clases y una


estructura de directorios con muchos niveles, requiere
mucho trabajo incluir todas las clases necesarias
indicando correctamente la ruta de cada clase.

20

Herramientas comunes

Carga automtica de clases:

Symfony incluye una funcin spl_autoload_register()


para evitar la necesidad de los include y as poder
escribir directamente:
$miObjeto = new MiClase();

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

En este caso, Symfony busca la definicin de la clase


MiClase en todos los archivos con extensin .php que
se encuentran en alguno de los directorios lib/ del
proyecto. Si se encuentra la definicin de la clase, se
incluye de forma automtica.

21

Instalar Symfony

Instalar Symfony
Symfony es un framework creado con PHP 5 por
lo que es necesario disponer de esta versin.
Formas de instalar Symfony:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Sandbox
PEAR
SVN

(explicaremos la forma ms comn, usando PEAR)

23

Instalar Symfony
El paquete PEAR de Symfony incluye las libreras
propias de Symfony y todas sus dependencias.
Adems, tambin contiene un script que permite
extender la lnea de comandos del sistema para
que funcione el comando symfony.
Para instalar Symfony de esta manera, en primer
lugar se debe aadir el canal Symfony a PEAR
mediante este comando:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

> pear channel-discover pear.symfony-project.com

24

Instalar Symfony

Una vez aadido el canal, ya es posible instalar la


ltima versin estable de Symfony mediante el
siguiente comando:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

> pear install symfony/symfony


downloading symfony-1.1.0.tgz ...
Starting to download symfony-1.1.0.tgz (1,283,270 bytes)
.................................................................
.................................................................
.............done: 1,283,270 bytes
install ok: channel://pear.symfony-project.com/symfony-1.1.0

Para asegurarse de que se ha instalado


correctamente, ejecuta:
> symfony -V
symfony version 1.1.0 (/path/to/the/pear/symfony/lib/dir)

25

Instalar Symfony

Crear una aplicacin web:

Seguiremos dos pasos:


Crear el proyecto
Crear la aplicacin

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Crear el proyecto:
> mkdir ~/miproyecto
> cd ~/miproyecto
> symfony generate:project miproyecto

Symfony crear la estructura bsica del projecto

26

Instalar Symfony

Crear la aplicacin:
> php symfony generate:app miaplicacion

El comando anterior crea un directorio llamado miaplicacion/


dentro del directorio apps/ que se encuentra en la raz del
proyecto.
Por defecto se crea una configuracin bsica de la
aplicacin y una serie de directorios para la aplicacin
En el directorio web del proyecto tambin se crean algunos
archivos PHP correspondientes a los controladores frontales
de cada uno de los entornos de ejecucin de la aplicacin:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

27

Instalar Symfony

Configurar el servidor web:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Los scripts que se encuentran en el directorio web/


son los nicos puntos de entrada a la aplicacin.
Por este motivo, debe configurarse el servidor web
para que puedan ser accedidos desde Internet.
Para ello configuraremos un servidor virtual en
Apache.

28

Instalar Symfony

Configurar un servidor virtual:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Ejemplo en apache/conf/httpd.conf
<VirtualHost *>
ServerName miaplicacion.ejemplo.com
DocumentRoot "/home/jordi/miproyecto/web"
DirectoryIndex index.php
Alias /sf /$sf_symfony_data_dir/web/sf
<Directory "/$sf_symfony_data_dir/web/sf">
AllowOverride All
Allow from All
</Directory>
<Directory "/home/jordi/miproyecto/web">
AllowOverride All
Allow from All
</Directory>
</VirtualHost>

En la configuracin, se debe sustituir la variable


$sf_symfony_data_dir por la ruta real del directorio de datos de
Symfony.
29

Instalar Symfony

Configurar un servidor virtual:

Para poder probar el ejemplo anterior en nuestro propio


ordenador de desarrollo, aadiremos la siguiente lnea a
/etc/hosts

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

127.0.0.1

miaplicacion.ejemplo.com

30

Instalar Symfony

Una vez configurado, reiniciamos Apache y accederemos a


la aplicacin en el navegador en la direccin:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

http://miaplicacion.ejemplo.com/miaplicacion_dev.php/

31

Instalar Symfony
Symfony utiliza la reescritura de URL para mostrar "URL
limpias" en la aplicacin, es decir, URL con mucho sentido,
optimizadas para buscadores y que ocultan a los usuarios
los detalles tcnicos internos de la aplicacin.
Para que funcione correctamente la reescritura de URL, es
necesario que Apache est compilado con el mdulo
mod_rewrite o al menos que est instalado el mdulo
mod_rewrite como mdulo DSO. En este ltimo caso, la
configuracin de Apache debe contener las siguientes lneas
en el archivo httpd.conf:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

AddModule mod_rewrite.c
LoadModule rewrite_module
modules/mod_rewrite.so

32

Intro. a la creacin de pginas

Intro. a la creacin de pginas


En esta seccin se muestra como crear un
mdulo, que es el elemento que agrupa a las
pginas.
Tambin se aprende cmo crear una pgina, que
a su vez se divide en una accin y una plantilla,
siguiendo la arquitectura MVC. Las interacciones
bsicas con las pginas se realizan mediante
enlaces y formularios, por lo que tambin se
muestra como incluirlos en las plantillas y como
manejarlos en las acciones.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

34

Intro. a la creacin de pginas

Crear el esqueleto del mdulo:

Antes de crear una pgina es necesario crear un


mdulo, que inicialmente no es ms que una
estructura vaca de directorios y archivos.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

> cd ~/miproyecto
> symfony generate:module miaplicacion mimodulo
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>

dir+
dir+
file+
dir+
dir+
dir+
file+
dir+
file+
tokens
tokens
tokens

~/miproyecto/apps/miaplicacion/modules/mimodulo
~/miproyecto/apps/miaplicacion/modules/mimodulo/actions
~/miproyecto/apps/miaplicacion/modules/mimodulo/actions/actions.class.php
~/miproyecto/apps/miaplicacion/modules/mimodulo/config
~/miproyecto/apps/miaplicacion/modules/mimodulo/lib
~/miproyecto/apps/miaplicacion/modules/mimodulo/templates
~/miproyecto/apps/miaplicacion/modules/mimodulo/templates/indexSuccess.php
~/miproyecto/apps/miaplicacion/modules/mimodulo/validate
~/miproyecto/test/functional/miaplicacion/mimoduloActionsTest.php
~/miproyecto/test/functional/miaplicacion/mimoduloActionsTest.php
~/miproyecto/apps/miaplicacion/modules/mimodulo/actions/actions.class.php
~/miproyecto/apps/miaplicacion/modules/mimodulo/templates/indexSuccess.php

35

Intro. a la creacin de pginas

El archivo actions.class.php redirige la accin a la


pgina de bienvenida del mdulo por defecto.
El archivo templates/indexSuccess.php est vaco.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

<?php
class mimoduloActions extends sfActions
{
public function executeIndex()
{
$this->forward('default', 'module');
}
}

Para visualizar la pgina generada:

http://miaplicacion.ejemplo.com/miaplicacion_dev.php/mimodulo/index

36

Intro. a la creacin de pginas

Aadir una pgina:

La lgica o cdigo de las pginas se define en la accin


La presentacin se define en las plantillas.

(Las pginas estticas que no requieren de ninguna lgica necesitan


definir una accin vaca)

Aadir una accin:

La pgina que muestra el mensaje "Hola Mundo!" ser


accedida mediante una accin llamada miAccion.
Para crearla, solamente es necesario aadir el mtodo
executeMiAccion en la clase mimoduloActions.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

<?php
class mimoduloActions extends sfActions
{
public function executeMiAccion()
{
}
}
37

Intro. a la creacin de pginas


El nombre del mtodo de la accin siempre es execute +
Xxxxxxx + (), donde la segunda parte del nombre es el
nombre de la accin con la primera letra en maysculas.
Para acceder a la pgina:

http://miaplicacion.ejemplo.com/miaplicacion_dev.php/mimodulo/miAccion

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Symfony mostrar un mensaje de error indicando que la


plantilla miAccionSuccess.php no existe. Se trata de un error
normal por el momento, ya que las pginas siempre estn
formadas por una accin y una plantilla.

38

Intro. a la creacin de pginas

Aadir una plantilla:

La accin espera una plantilla para mostrarse en pantalla.


Una plantilla es un archivo que est ubicado en el directorio
templates/ de un mdulo, y su nombre est compuesto por
el nombre de la accin y el resultado de la misma. El
resultado por defecto es success (exitoso), por lo que el
archivo de plantilla que se crea para la accin miAccion se
llamar miAccionSuccess.php.
La plantilla mimodulo/templates/miAccionSuccess.php

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

<p>Hola, mundo!</p>

39

Intro. a la creacin de pginas

Transfiriendo informacin de la accin a la


plantilla:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

La tarea de la accin es realizar los clculos


complejos, obtener datos, realizar comprobaciones, y
crear o inicializar las variables necesarias para que se
presenten o se utilicen en la plantilla.
Los atributos de la clase de la accin (disponibles va
$this->nombreDeVariable en la accin), estn
directamente accesibles en la plantilla en el mbito
global (va $nombreVariable).

40

Intro. a la creacin de pginas

Accin:
<?php

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

class mimoduloActions extends sfActions


{
...

public function executeMiAccion()


{
$hoy = getdate();
$this->hora = $hoy['hours'];
}

Plantilla:
<p>Hola, Mundo!</p>
<?php if ($hora >= 18): ?>
<p>Quizs debera decir buenas tardes. Ya son las <?
php echo $hora ?>.</p>
<?php endif; ?>
41

Intro. a la creacin de pginas

Formularios:

Se pueden incluir elementos de formulario en las


plantillas de manera tradicional, pero Symfony provee
helpers que hacen mucho ms sencilla esta tarea.
Helper:
Funcin PHP definida en Symfony que est pensada para
ser utilizada desde las plantillas.
Devuelven algo de cdigo HTML.
Es ms rpido de usar que insertar el cdigo HTML
manualmente.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

42

Intro. a la creacin de pginas

Plantilla con helpers:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

<p>Hola, Mundo!</p>
<?php if ($hora >= 18): ?>
<p>Quizs debera decir buenas tardes. Ya son las <?php echo $hora ?>.</p>
<?php endif; ?>
<?php echo form_tag('mimodulo/otraAccion') ?>
<?php echo label_for('nombre', 'Cmo te llamas?') ?>
<?php echo input_tag('nombre') ?>
<?php echo submit_tag('Ok') ?>
</form>

43

Intro. a la creacin de pginas

Obteniendo informacin de la peticin:

El mtodo getRequestParameter() del objeto sfActions


permite recuperar desde la accin los datos relacionados
con la informacin que enva el usuario a travs de un
formulario (normalmente en una peticin POST) o a travs
de la URL (mediante una peticin GET).

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

<?php
class mimoduloActions extends sfActions
{
...
public function executeOtraAccion()
{
$this->nombre = $this->getRequestParameter('nombre');
}
}

44

Intro. a la creacin de pginas

Obteniendo informacin de la peticin:

Desde la plantilla se tiene acceso a un objeto llamado


$sf_params, el cual ofrece un mtodo get() para recuperar
los parmetros de la peticin, tal y como el mtodo
getRequestParameter() en la accin.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

<p>Hola, <?php echo $sf_params->get('nombre') ?>!</p>

45

MVC

MVC

La implementacin del MVC que realiza Symfony

La capa del Modelo

Abstraccin de la base de datos


Acceso a los datos

La capa de la Vista
Vista
Plantilla
Layout

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

La capa del Controlador


Controlador frontal
Accin

47

MVC
En total son siete scripts. Afortunadamente,
Symfony simplifica este proceso.
En primer lugar, el controlador frontal y el layout
son comunes para todas las acciones de la
aplicacin. Se pueden tener varios controladores
y varios layouts, pero solamente es obligatorio
tener uno de cada.
El controlador frontal es un componente que slo
tiene cdigo relativo al MVC, por lo que no es
necesario crear uno, ya que Symfony lo genera
de forma automtica.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

48

MVC

Las clases de la capa del modelo se generan


automticamente, en funcin de la estructura de
datos de la aplicacin.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

La librera Propel se encarga de esta generacin


automtica, ya que crea el esqueleto o estructura
bsica de las clases y genera automticamente el
cdigo necesario.
Cuando Propel encuentra restricciones de claves
forneas (o externas) o cuando encuentra datos de
tipo fecha, crea mtodos especiales para acceder y
modificar esos datos, por lo que la manipulacin de
datos se simplifica.

49

MVC

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

La abstraccin de la base de datos es


completamente invisible al programador, ya que la
realiza otro componente especfico llamado Creole.

Por ltimo, la lgica de la vista se puede


transformar en un archivo de configuracin
sencillo, sin necesidad de programarla.

50

MVC: Controlador

MVC: Controlador
La capa del controlador contiene el cdigo que
liga la lgica de negocio con la presentacin.
Est dividida en varios componentes que se
utilizan para diversos propsitos:

Controlador frontal

nico punto de entrada a la aplicacin.


Carga la configuracin y determina la accin a ejecutarse.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Acciones

Contienen la lgica de la aplicacin.


Verifican la integridad de las peticiones
Preparan los datos requeridos por la capa de presentacin.

Objetos request, response y session

Dan acceso a los parmetros de la peticin, las cabeceras


de las respuestas y a los datos persistentes del usuario.
Se utilizan muy a menudo en la capa del controlador.

52

MVC: Controlador

Filtros

Trozos de cdigo ejecutados para cada peticin, antes o


despus de una accin.
Por ejemplo, los filtros de seguridad y validacin son
comnmente utilizados en aplicaciones web.
Puedes extender el framework creando tus propios filtros.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

53

MVC: Controlador

El Controlador Frontal:

Todas las peticiones web son manejadas por un solo


controlador frontal.
Cuando el controlador frontal recibe una peticin,
utiliza el sistema de enrutamiento para asociar el
nombre de una accin y el nombre de un mdulo con
la URL escrita (o pinchada) por el usuario.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Por ejemplo, la siguientes URL llama al script index.php (que


es el controlador frontal) y ser entendido como llamada a la
accin miAccion del mdulo mimodulo:

http://miaplicacion.ejemplo.com/index.php/mimodulo/miAccion

54

MVC: Controlador

Acciones:

Contienen toda la lgica de la aplicacin.


Las acciones utilizan el modelo y definen variables
para la vista. Cuando se realiza una peticin web en
una aplicacin Symfony, la URL define una accin y
los parmetros de la peticin.
Ejecucin y creacin de acciones:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Ver seccin: Introduccin a la creacin de pginas.

55

MVC: Controlador

Acciones:

Obteniendo Informacin en las Acciones:

class mimoduloActions extends sfActions


{
public function executeIndex()
{
// Obteniendo parametros de la peticin
$password
= $this->getRequestParameter('password');

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

// Obteniendo informacin del controlador


$nombreModulo = $this->getModuleName();
$nombreAccion = $this->getActionName();
// Obteniendo objetos del ncleo del framework
$peticion
= $this->getRequest();
$sesionUsuario = $this->getUser();
$respuesta
= $this->getResponse();
$controlador
= $this->getController();
$contexto
= $this->getContext();
// Creando variables de la accin para pasar informacin a la plantilla
$this->setVar('parametro', 'valor');
$this->parametro = 'valor';
// Versin corta.
}
}

56

MVC: Controlador

Acciones:

Obteniendo Informacin en las Acciones:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

En una accin, el mtodo getContext() devuelve el singleton


de un objeto muy til que guarda una referencia a todos los
objetos del ncleo de Symfony relacionados con una
peticin dada, y ofrece un mtodo accesor para cada uno de
ellos:
-

sfController: El objeto controlador (->getController())


sfRequest: El objeto de la peticin (->getRequest())
sfResponse: El objeto de la respuesta (->getResponse())
sfUser: El objeto de la sesin del usuario (->getUser())
sfDatabaseConnection: La conexin a la base de datos
(->getDatabaseConnection())
sfLogger: El objeto para los logs (->getLogger())
sfI18N: El objeto de internacionalizacin (->getI18N())

Se puede llamar al singleton sfContext::getInstance() desde


cualquier parte del cdigo.
57

MVC: Controlador

Acciones:

Terminacin de las Acciones:

Existen varias alternativas posibles.


El valor retornado por el mtodo de la accin determina
como ser producida la vista. Para especificar la plantilla
que se utiliza al mostrar el resultado de la accin, se
emplean las constantes de la clase sfView.
Si existe una vista por defecto que se debe llamar, la accin
debera terminar de la siguiente manera:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

return sfView::SUCCESS;

Symfony buscar entonces una plantilla llamada


nombreAccionSuccess.php (por defecto)
Si se omite la sentencia return en el mtodo de la accin,
Symfony tambin buscar una plantilla llamada
nombreAccionSuccess.php.
Las acciones vacas tambin siguen este comportamiento.

58

MVC: Controlador

Acciones:

Terminacin de las Acciones:

Success

return sfView::SUCCESS;

Error

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

return sfView::ERROR;

Personalizada
return 'MiResultado';

No utilizar ninguna vista


return sfView::NONE;

Slo cabeceras (por ejemplo la cabecera X-JSON)


return sfView::HEADER_ONLY;
59

MVC: Controlador

Acciones:

Saltando a Otra Accin:

En algunos casos, la ejecucin de un accin termina


solicitando la ejecucin de otra accin.
La clase de la accin provee dos mtodos para ejecutar otra
accin:

Si la accin pasa la llamada hacia otra accin (forward):

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

$this->forward('otroModulo', 'index');

Si la accin produce un redireccionamiento web (redirect):


$this->redirect('otroModulo/index');
$this->redirect('http://www.google.com/');

60

MVC: Controlador

Accediendo a la Peticin:

Nombre

Funcin

Ejemplo de salida producida

getMethod()

Mtodo de la peticin

Devuelve la constante sfRequest::GET o


sfRequest::POST

getMethodName()

Nombre del mtodo de peticin

POST

getHttpHeader('Server')

Valor de una cabecera HTTP

Apache/2.0.59 (Unix) DAV/2 PHP/5.1.6

getCookie('foo')

Valor de una cookie

valor

isXmlHttpRequest() (1)

Es una peticin AJAX?

true

isSecure()

Es una peticin SSL?

true

hasParameter('parametro')

Existe el parmetro en la
peticin?

true

getParameter('parametro')

Valor del parmetro

valor

getParameterHolder()->getAll()

Array de todos los parmetros de la peticin

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Informacin sobre la peticin

Parmetros de la peticin

61

MVC: Controlador

Accediendo a la Peticin:

Nombre

Funcin

Ejemplo de salida producida

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Informacin relacionada con la URI

http://localhost/miaplicacion_dev.php/mimodulo/mi

getUri()

URI completa

getPathInfo()

Informacin de la ruta

/mimodulo/miaccion

getReferer() (2)

Valor del "referer" de la peticin

http://localhost/miaplicacion_dev.php/

getHost()

Nombre del Host

localhost

getScriptName()

Nombre y ruta del controlador


frontal

miaplicacion_dev.php

Informacin del navegador del cliente


getLanguages()

Array de los lenguajes


aceptados

Array( [0] => es [1] => es_CA [2] =>


en_US [3] => en )

getCharsets()

Array de los juegos de


caracteres aceptados

Array( [0] => ISO-8859-1 [1] => UTF-8 [2]


=> * )

getAcceptableContentType()

Array de los tipos de contenidos


aceptados

Array( [0] => text/xml [1] => text/html

(1) Funciona slo con prototype (2) A veces es bloqueado por los proxy
62

MVC: Controlador

Sesiones de Usuario:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Symfony maneja automticamente las sesiones del


usuario y es capaz de almacenar datos de forma
persistente entre peticiones.

class mimoduloActions extends sfActions


{
public function executePrimeraPagina()
{
$nombre = $this->getRequestParameter('nombre');

// Guardar informacin en la sesin del usuario


$this->getUser()->setAttribute('nombre', $nombre);

public function executeSegundaPagina()


{
// Obtener informacin de la sesin del usuario con un valor por
defecto
$nombre = $this->getUser()->getAttribute('nombre', 'Annimo');
}
}
63

MVC: Controlador

Sesiones de Usuario:

Eliminando informacin de la sesin del usuario.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

class mimoduloActions extends sfActions


{
public function executeBorraNombre()
{
$this->getUser()->getAttributeHolder()->remove('nombre');
}
public function executeLimpia()
{
$this->getUser()->getAttributeHolder()->clear();
}
}

64

MVC: Vista

MVC: Vista
Se encarga de producir las pginas que se
muestran como resultado de las acciones.
La vista en Symfony est compuesta por diversas
partes, estando cada una de ellas especialmente
preparada para que pueda ser fcilmente
modificable por la persona que normalmente
trabaja con cada aspecto del diseo de las
aplicaciones.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

66

MVC: Vista

Plantillas:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Su contenido est formado por cdigo HTML y algo de


cdigo PHP sencillo, normalmente llamadas a las
variables definidas en la accin y algunos helpers.
Plantilla de ejemplo indexSuccess.php:

<h1>Bienvenido</h1>
<p>Hola de nuevo, <?php echo $nombre ?>!</p>
<ul>Qu es lo que quieres hacer?
<li><?php echo link_to('Leer los ltimos artculos', 'articulo/leer') ?></li>
<li><?php echo link_to('Escribir un nuevo artculo', 'articulo/escribir') ?></li>
</ul>

67

MVC: Vista

Helpers:

Los helpers son funciones de PHP que devuelven


cdigo HTML y que se utilizan en las plantillas.
<?php echo input_tag('nick') ?>
=> <input type="text" name="nick" id="nick" value="" />

Helpers de Symfony:

Helper: se necesita para incluir otros helpers


Tag: helper bsico para etiquetas y que utilizan casi todos
los helpers
Url: helpers para la gestin de enlaces y URL
Asset: helpers que aaden elementos a la seccin <head>
del cdigo HTML y que proporcionan enlaces sencillos a
elementos externos (imgenes, archivos JavaScript, hojas
de estilo, etc.)

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

68

MVC: Vista

Helpers:

Helpers de Symfony:

Partial: helpers que permiten incluir trozos de plantillas


Cache: manipulacin de los trozos de cdigo que se han
aadido a la cache
Form: helpers para los formularios

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Adems disponemos de la posibilidad de crear


nuestros propios helpers.

69

MVC: Vista

Layout de las pginas:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Las plantillas anteriores no son un documento XHTML


vlido. Le faltan la definicin del DOCTYPE y las
etiquetas <html> y <body>.
El motivo es que estos elementos se encuentran en
otro lugar de la aplicacin, un archivo llamado
layout.php que contiene el layout de la pgina.
Este archivo, que tambin se denomina plantilla
global, almacena el cdigo HTML que es comn a
todas las pginas de la aplicacin, para no tener que
repetirlo en cada pgina.

70

MVC: Vista

Layout de las pginas:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

El contenido de la plantilla se integra en el layout:

71

MVC: Vista

Fragmentos de cdigo:

En ocasiones es necesario incluir cierto cdigo HTML


o PHP en varias pginas.
Symfony define 3 alternativas:

Elementos parciales (partial):


-

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Componentes (component):
-

Si el fragmento contiene poca lgica, se puede utilizar un archivo de


plantilla al que se le pasan algunas variables.
Si la lgica es compleja (por ejemplo se debe acceder a los datos del
modelo o se debe variar los contenidos en funcin de la sesin) es
preferible separar la presentacin de la lgica.

Slot:
-

Si el fragmento va a reemplazar una zona especfica del layout, para


la que puede que exista un contenido por defecto.

72

MVC: Vista

Partial:

Es un trozo de cdigo de plantilla que se puede reutilizar.


Por ejemplo, en una aplicacin de publicacin, el cdigo de
plantilla que se encarga de mostrar un artculo se utiliza en
la pgina de detalle del artculo, en la pgina que lista los
mejores artculo y en la pgina que muestra los ltimos
artculos.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

73

MVC: Vista

Partial:

Son archivos que se encuentran en el directorio templates/,


y que contienen cdigo HTML y cdigo PHP.
El nombre del archivo de un elemento parcial siempre
comienza con un guin bajo (_).
Los elementos parciales se incluyen mediante el helper
include_partial(), al que se le pasa como parmetro el
nombre del mdulo y el nombre del elemento parcial.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

// Incluir el elemento pacial de


miaplicacion/modules/mimodulo/templates/_miparcial1.php
// Como la plantilla y el elemento parcial estn en el mismo mdulo,
// se puede omitir el nombre del mdulo
<?php include_partial('miparcial1') ?>
// Incluir el elemento parcial de
miaplicacion/modules/otromodulo/templates/_miparcial2.php
// En este caso es obligatorio indicar el nombre del mdulo
<?php include_partial('otromodulo/miparcial2') ?>
// Incluir el elemento parcial de miaplicacion/templates/_miparcial3.php
// Se considera que es parte del mdulo 'global'
<?php include_partial('global/miparcial3') ?>

74

MVC: Vista

Partial:

No tienen acceso automtico a las variables definidas por la


accin que ha incluido la plantilla en la que se encuentra el
elemento parcial.
La plantilla pasa la variable al elemento parcial, en
mimodulo/templates/indexSuccess.php:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

<p>Hola Mundo!</p>
<?php include_partial('miparcial', array('mitotal' => $total)) ?>

75

MVC: Vista

Componentes:

Al igual que el patrn MVC se aplica a las acciones y las


plantillas, es posible dividir un elemento parcial en su parte
de lgica y su parte de presentacin. En este caso, se
necesitan los componentes.
Un componente es como una accin, solo que mucho ms
rpido.
La lgica del componente se guarda en una clase que
hereda de sfComponents y que se debe guardar en el
archivo action/components.class.php.
Su presentacin se guarda en un elemento parcial.
Los mtodos de la clase sfComponents empiezan con la
palabra execute, como sucede con las acciones, y pueden
pasar variables a su presentacin de la misma forma en la
que se pasan variables en las acciones.
Los elementos parciales que se utilizan como presentacin
de un componente, se deben llamar igual que los
componentes, sustituyendo la palabra execute por un guin
76
bajo.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

MVC: Vista

Componentes:

La clase de los componentes, en


modules/news/actions/components.class.php

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

<?php
class newsComponents extends sfComponents
{
public function executeHeadlines()
{
$c = new Criteria();
$c->addDescendingOrderByColumn(NewsPeer::PUBLISHED_AT);
$c->setLimit(5);
$this->news = NewsPeer::doSelect($c);
}
}

El elemento parcial, en
modules/news/templates/_headlines.php
<div>
<h1>ltimas noticias</h1>
<ul>
<?php foreach($news as $headline): ?>
<li>
<?php echo $headline->getPublishedAt() ?>
<?php echo link_to($headline->getTitle(),'news/show?id='.$headline>getId()) ?>
</li>
<?php endforeach ?>
</ul>
</div>

77

MVC: Vista

Componentes:

Cada vez que se necesite el componente en una plantilla, se


puede incluir de la siguiente forma:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

<?php include_component('news', 'headlines') ?>

78

MVC: Vista

Slots:

En muchas ocasiones se necesitan fragmentos de cdigo


que rellenen un layout con ms de una zona variable.
Por ejemplo

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Se puede necesitar aadir etiquetas personalizadas en la seccin


<head> del layout en funcin del contenido de la accin.
Tambin se puede dar el caso de un layout que tiene una zona de
contenidos dinmicos que se rellena con el resultado de la accin y
muchas otras zonas pequeas que tienen un contenido por defecto
definido en el layout pero que puede ser modificado en la plantilla.

79

MVC: Vista

Slots:

Un slot es una zona que se puede definir en cualquier


elemento de la vista (layout, plantilla o elemento parcial).
La forma de rellenar esa zona es similar a establecer el valor
de una variable.
El cdigo de relleno se almacena de forma global en la
respuesta, por lo que se puede definir en cualquier sitio
(layout, plantilla o elemento parcial).
Se debe definir un slot antes de utilizarlo y tambin hay que
tener en cuenta que el layout se ejecuta despus de la
plantilla (durante el proceso de decoracin) y que los
elementos parciales se ejecutan cuando los llama una
plantilla.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

80

MVC: Vista

Slots:

Imaginemos que se dispone de un layout con una zona para


la plantilla y 2 slots.
El valor de los slots se define en la plantilla.
Durante el proceso de decoracin, el layout integra en su
interior el cdigo de la plantilla, por lo que los slots se
rellenan con los valores que se han definido anteriormente.
De esta forma, el lateral y el pie de pgina pueden depender
de la accin. Se puede aproximar a la idea de tener un
layout con uno o ms agujeros que se rellenan con otro
cdigo.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

81

MVC: Vista

Slots:

Incluir un slot llamado lateral en el layout

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

<div id="lateral">
<?php if (has_slot('lateral')): ?>
<?php include_slot('lateral') ?>
<?php else: ?>
<!-- cdigo del lateral por defecto -->
<h1>Zona cuyo contenido depende del contexto</h1>
<p>Esta zona contiene enlaces e informacin sobre
el contenido principal de la pgina.</p>
<?php endif; ?>
</div>

Redefiniendo el contenido del slot lateral en la plantilla


...
<?php slot('lateral') ?>
<!-- Cdigo especfico para el lateral de esta
plantilla -->
<h1>Detalles del usuario</h1>
<p>Nombre: <?php echo $user->getName() ?></p>
<p>Email: <?php echo $user->getEmail() ?></p>
<?php end_slot() ?>

82

MVC: Vista

Configuracin de la vista:

En la vista, todo lo que no es HTML se considera


configuracin de la propia vista y Symfony permite 2
formas de manipular esa configuracin:

Mediante el archivo de configuracin view.yml.


-

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Se utiliza cuando los valores de configuracin no dependen del


contexto o de alguna consulta a la base de datos.

Aadir los atributos directamente en el objeto sfResponse


durante la accin
-

Cuando se trabaja con valores dinmicos que cambian con cada


accin.

83

MVC: Vista

El archivo view.yml:

Cada mdulo contiene un archivo view.yml que define las


opciones de su propia vista.
De esta forma, es posible definir en un nico archivo las
opciones de la vista para todo el mdulo entero y las
opciones para cada vista.
Las claves de primer nivel en el archivo view.yml son el
nombre de cada mdulo que se configura.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

editSuccess:
metas:
title: Edita tu perfil
editError:
metas:
title: Error en la edicin del perfil
all:
stylesheets: [mi_estilo]
metas:
title: Mi sitio web

84

MVC: Vista

El archivo view.yml:

Archivo de configuracin de la vista de la aplicacin, en


apps/miaplicacion/config/view.yml

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

default:
http_metas:
content-type: text/html
metas:
title:
robots:
description:
keywords:
language:

symfony project
index, follow
symfony project
symfony, project
en

stylesheets:

[main]

javascripts:

[ ]

has_layout:
layout:

on
layout

85

MVC: Vista

El objeto respuesta (response):

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

class mimoduloActions extends sfActions


{
public function executeIndex()
{
$respuesta = $this->getResponse();
// Cabeceras HTTP
$respuesta->setContentType('text/xml');
$respuesta->setHttpHeader('Content-Language', 'en');
$respuesta->setStatusCode(403);
$respuesta->addVaryHttpHeader('Accept-Language');
$respuesta->addCacheControlHttpHeader('no-cache');
// Cookies
$respuesta->setCookie($nombre, $contenido, $expiracion, $ruta,
$dominio);

// Atributos Meta y cabecera de la pgina


$respuesta->addMeta('robots', 'NONE');
$respuesta->addMeta('keywords', 'palabra1 palabra2');
$respuesta->setTitle('Mi Pgina de Ejemplo');
$respuesta->addStyleSheet('mi_archivo_css');
$respuesta->addJavaScript('mi_archivo_javascript');

86

MVC: Modelo

MVC: Modelo
El componente que gestiona el modelo es una
capa de tipo ORM (object/relational mapping)
realizada mediante el proyecto Propel
(http://propel.phpdb.org/).
El acceso y la modificacin de los datos
almacenados en la base de datos se realiza
mediante objetos.
Este comportamiento permite un alto nivel de
abstraccin y permite una fcil portabilidad.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

88

MVC: Modelo

Esquema de base de datos

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Para crear el modelo de objetos de datos se debe


traducir el modelo relacional de la base de datos a un
modelo de objetos de datos.
Para realizar ese mapeo o traduccin, el ORM
necesita una descripcin del modelo relacional, que se
llama "esquema" (schema).
En el esquema se definen las tablas, sus relaciones y
las caractersticas de sus columnas.
La sintaxis para definir los esquemas hace uso del
formato YAML.
Los archivos schema.yml deben guardarse en el
directorio miproyecto/config/.
89

MVC: Modelo

Ejemplo de esquema:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Ejemplo de schema.yml
propel:
blog_article:
_attributes:
id:
title:
content:
created_at:
blog_comment:
_attributes:
id:
article_id:
author:
content:
created_at:

{ phpName: Article }
varchar(255)
longvarchar
{ phpName: Comment }
varchar(255)
longvarchar

90

MVC: Modelo

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Cada tabla puede definir varios atributos, incluyendo el


atributo phpName (que es el nombre de la clase PHP
que ser generada para esa tabla). Si no se menciona
el atributo phpName para una tabla, Symfony crea una
clase con el mismo nombre que la tabla al que se
aplica las normas del camelCase.
Las tablas contienen columnas y el valor de las
columnas se puede definir de 3 formas diferentes:

Si no se indica nada, Symfony intenta adivinar los atributos


ms adecuados para la columna en funcin de su nombre y
de una serie de convenciones.
-

Por ejemplo, en el listado anterior no es necesario definir la columna


id. Symfony por defecto la trata como de tipo entero (integer), cuyo
valor se auto-incrementa y adems, clave principal de la tabla.

91

MVC: Modelo
-

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

En la tabla blog_comment, la columna article_id se trata como una


clave externa a la tabla blog_article (las columnas que acaban en _id
se consideran claves externas, y su tabla relacionada se determina
automticamente en funcin de la primera parte del nombre de la
columna).
Las columnas que se llaman created_at automticamente se
consideran de tipo timestamp. Para este tipo de columnas, no es
necesario definir su tipo.

92

MVC: Modelo

Si solo se define un atributo, se considera que es el tipo de


columna.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Symfony entiende los tipos de columna habituales: boolean, integer,


float, date, varchar(tamao), longvarchar (que se convierte, por
ejemplo, en tipo text en MySQL), etc. Para contenidos de texto de
ms de 256 caracteres, se utiliza el tipo longvarchar, que no tiene
tamao definido (pero que no puede ser mayor que 65KB en
MySQL). Los tipos date y timestamp tienen las limitaciones
habituales de las fechas de Unix y no pueden almacenar valores
anteriores al 1 de Enero de 1970. Como puede ser necesario
almacenar fechas anteriores (por ejemplo para las fechas de
nacimiento), existe un formato de fechas "anteriores a Unix" que son
bu_date and bu_timestamp.

Si se necesitan definir otros atributos a la columna


-

Por ejemplo su valor por defecto, si es obligatorio o no, etc.), se


indican los atributos como pares clave: valor.

93

MVC: Modelo

Las clases del modelo:

El esquema se utiliza para construir las clases del


modelo que necesita la capa del ORM.
Para reducir el tiempo de ejecucin de la aplicacin,
estas clases se generan mediante una tarea de lnea
de comandos llamada propel:build-model.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

> symfony propel:build-model

94

MVC: Modelo

Al ejecutar ese comando, se analiza el esquema y se


generan las clases base del modelo, que se
almacenan en el directorio lib/model/om/ del proyecto:
BaseArticle.php
BaseArticlePeer.php
BaseComment.php
BaseCommentPeer.php

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Adems, se crean las verdaderas clases del modelo


de datos en el directorio lib/model/:
Article.php
ArticlePeer.php
Comment.php
CommentPeer.php

95

MVC: Modelo

Clases base y clases personalizadas:

Por qu es til mantener 2 versiones del modelo de objetos


de datos en 2 directorios diferentes?
-

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Puede ser necesario aadir mtodos y propiedades personalizadas


en los objetos del modelo.
Tambin es posible que a medida que el proyecto se est
desarrollando, se aadan tablas o columnas.
Adems, cada vez que se modifica el archivo schema.yml se deben
regenerar las clases del modelo de objetos mediante el comando
propel:build-model. Si se aaden los mtodos personalizados en las
clases que se generan, se borraran cada vez que se vuelven a
generar esas clases.

Las clases con nombre Base del directorio lib/model/om/ son


las que se generan directamente a partir del esquema.
Nunca se deberan modificar esas clases, porque cada vez
que se genera el modelo, se borran todas las clases.
Las clases de objetos propias que estn en el directorio
lib/model heredan de las clases con nombre Base. Estas
clases no se modifican cuando se ejecuta la tarea
propel:build-model, por lo que son las clases en las que se
96
aaden los mtodos propios.

MVC: Modelo

Archivo de ejemplo de una clase del modelo, en


lib/model/Article.php
<?php
class Article extends BaseArticle
{
}

Clases objeto y clases "peer":

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Article y Comment son clases objeto que representan un


registro de la base de datos. Permiten acceder a las
columnas de un registro y a los registros relacionados. Por
tanto, es posible obtener el ttulo de un artculo invocando un
mtodo del objeto Article:
$articulo = new Article();
...
$titulo = $articulo->getTitle();

97

MVC: Modelo

ArticlePeer y CommentPeer son clases de tipo "peer"; es


decir, clases que tienen mtodos estticos para trabajar con
las tablas de la base de datos. Proporcionan los medios
necesarios para obtener los registros de las tablas. Sus
mtodos devuelven normalmente un objeto o una coleccin
de objetos de la clase objeto relacionada:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

$articulos = ArticlePeer::retrieveByPks(array(123, 124, 125));


// $articulos es un array de objetos de la clase Article

98

MVC: Modelo

Acceso a los datos

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

El acceso a los datos se realiza mediante objetos.


El modelo relacional y el modelo de objetos utilizan
conceptos similares:
Relacional

Orientado a objetos

Tabla

Clase

Fila, registro

Objeto

Campo, columna

Propiedad

99

MVC: Modelo

Obtener el valor de una columna:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Al construir el modelo se crea una clase de objeto base que


contiene una serie de constructores y accesores por defecto
en funcin de la definicin de cada columna: los mtodos
new, getXXX() y setXXX() permiten crear y obtener las
propiedades de los objetos:

$articulo = new Article();


$articulo->setTitle('Mi primer artculo');
$articulo->setContent('Este es mi primer artculo. \n Espero que te guste.');
$titulo
= $articulo->getTitle();
$contenido = $articulo->getContent();
// Para establecer el valor de varios campos a la vez, se puede utilizar el
mtodo fromArray()
$articulo->fromArray(array(
'title'
=> 'Mi primer artculo',
'content' => 'Este es mi primer artculo. \n Espero que te guste.'
));

100

MVC: Modelo

Obtener los registros relacionados:

La columna article_id de la tabla blog_comment define


implcitamente una clave externa a la tabla blog_article.
Cada comentario est relacionado con un artculo y un
artculo puede tener muchos comentarios.
Las clases generadas contienen 5 mtodos que traducen
esta relacin a la forma orientada a objetos, de la siguiente
manera:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

$comentario->getArticle(): para obtener el objeto Article relacionado


$comentario->getArticleId(): para obtener el ID del objeto Article
relacionado
$comentario->setArticle($articulo): para definir el objeto Article
relacionado
$comentario->setArticleId($id): para definir el objeto Article
relacionado a partir de un ID
$articulo->getComments(): para obtener los objetos Comment
relacionados

101

MVC: Modelo

Las claves externas se traducen en un setter especial:

$comentario = new Comment();


$comentario->setAuthor('Steve');
$comentario->setContent('Es el mejor artculo que he ledo nunca!');
// Aadir este comentario al anterior objeto $articulo
$comentario->setArticle($articulo);

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

// Sintaxis alternativa
// Solo es correcta cuando el objeto artculo ya
// ha sido guardado anteriormente en la base de datos
$comentario->setArticleId($articulo->getId());

102

MVC: Modelo

Guardar datos:

Al utilizar el constructor new se crea un nuevo objeto, pero


no un registro en la tabla blog_article. Si se modifica el
objeto, tampoco se reflejan esos cambios en la base de
datos.
Para guardar los datos en la base de datos, se debe invocar
el mtodo save() del objeto.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

$articulo->save();

El ORM de Symfony detectar las relaciones entre objetos, por lo


que al guardar el objeto $articulo tambin se guarda el objeto
$comentario relacionado.
Tambin detecta si ya exista el objeto en la base de datos, por lo
que el mtodo save() a veces se traduce a una sentencia INSERT
de SQL y otras veces se traduce a una sentencia UPDATE.
La clave primaria se establece de forma automtica al llamar al
mtodo save(), por lo que despus de guardado, se puede obtener
la nueva clave primaria del objeto mediante $articulo->getId().
103

MVC: Modelo

Borrar datos:

Mediante el mtodo delete() del objeto relacionado.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

foreach ($articulo->getComments() as $comentario)


{
$comentario->delete();
}

104

MVC: Modelo

Obtener registros mediante la clave primaria:


$articulo = ArticlePeer::retrieveByPk(7);

En algunos casos, la clave primaria est formada por ms


de una columna. Es esos casos, el mtodo retrieveByPK()
permite indicar varios parmetros, uno para cada columna
de la clave primaria.
Tambin se pueden obtener varios objetos a la vez
mediante sus claves primarias, invocando el mtodo
retrieveByPKs(), que espera como argumento un array de
claves primarias.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

105

MVC: Modelo

Obtener registros mediante Criteria:

Cuando se quiere obtener ms de un registro, se debe


utilizar el mtodo doSelect() de la clase peer
correspondiente a los objetos que se quieren obtener.
Por ejemplo, para obtener objetos de la clase Article, se
llama al mtodo ArticlePeer::doSelect().
El primer parmetro del mtodo doSelect() es un objeto de
la clase Criteria, que es una clase para definir consultas
simples sin utilizar SQL, para conseguir la abstraccin de
base de datos.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

// Obtener todos los artculos


$c = new Criteria();
$articulos = ArticlePeer::doSelect($c);
// Filtrar y ordenar comentarios
$c = new Criteria();
$c->add(CommentPeer::AUTHOR, 'Steve');
$c->addAscendingOrderByColumn(CommentPeer::CREATED_AT);
$comentarios = CommentPeer::doSelect($c);

106

MVC: Modelo

Sintaxis de SQL y del objeto Criteria:

SQL

Criteria

WHERE columna = valor

->add(columna, valor);

WHERE columna <> valor

->add(columna, valor, Criteria::NOT_EQUAL);

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Otros operadores de comparacin


>,<

Criteria::GREATER_THAN, Criteria::LESS_THAN

>=, <=

Criteria::GREATER_EQUAL,
Criteria::LESS_EQUAL

IS NULL, IS NOT NULL

Criteria::ISNULL, Criteria::ISNOTNULL

LIKE, ILIKE

Criteria::LIKE, Criteria::ILIKE

IN, NOT IN

Criteria::IN, Criteria::NOT_IN

Otras palabras clave de SQL


ORDER BY columna ASC

->addAscendingOrderByColumn(columna);

ORDER BY columna DESC

->addDescendingOrderByColumn(columna);

LIMIT limite

->setLimit(limite)

OFFSET desplazamiento

->setOffset(desplazamiento)

FROM tabla1, tabla2 WHERE tabla1.col1 = tabla2.col2

->addJoin(col1, col2)

FROM tabla1 LEFT JOIN tabla2 ON tabla1.col1 = tabla2.col2

->addJoin(col1, col2, Criteria::LEFT_JOIN)

FROM tabla1 RIGHT JOIN tabla2 ON tabla1.col1 = tabla2.col2

->addJoin(col1, col2, Criteria::RIGHT_JOIN)

107

MVC: Modelo

Uso de consultas con cdigo SQL:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

A veces, no es necesario obtener los objetos, sino que solo


son necesarios algunos datos calculados por la base de
datos.

$conexion = Propel::getConnection();
$consulta = 'SELECT MAX(%s) AS max FROM %s';
$consulta = sprintf($consulta, ArticlePeer::CREATED_AT, ArticlePeer::TABLE_NAME);
$sentencia = $conexion->prepareStatement($consulta);
$resultset = $sentencia->executeQuery();
$resultset->next();
$max = $resultset->getInt('max');

108

MVC: Modelo

Conexiones con la base de datos

Archivo databases.yml que se encuentra en el


directorio config/

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

prod:
propel:
param:
hostspec:
username:
password:
all:
propel:
class:
param:
phptype:
hostspec:
database:
username:
password:
port:
encoding:
persistent:

miservidordatos
minombreusuario
xxxxxxxxxx

sfPropelDatabase
mysql
# fabricante de la base de datos
localhost
blog
login
passwd
80
utf8
# Codificacin utilizada para crear la tabla
true
# Utilizar conexiones persistentes

109

MVC: Modelo

Extender el modelo

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Si se incluye lgica de negocio propia, es necesario


extender el modelo aadiendo nuevos mtodos o
redefiniendo algunos de los existentes.
Por ejemplo, en el objeto Article se puede aadir un
mtodo mgico de PHP llamado __toString() de forma
que al mostrar un objeto de la clase Article se muestre
su ttulo.
<?php
class Article extends BaseArticle
{
public function __toString()
{
return $this->getTitle(); // getTitle() se hereda de BaseArticle
}
}

110

Enlaces y sistema de
enrutamiento

Enlaces y sistema de enrutamiento


El enrutamiento es un mecanismo que reescribe
las URL para simplificar su aspecto.
Symfony desasocia las URL externas y las URI
utilizadas internamente. La correspondencia entre
las dos es responsabilidad del sistema de
enrutamiento. Symfony simplifica este mecanismo
utilizando una sintaxis para las URI internas muy
similar a la de las URL habituales.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

// Sintaxis de las URI internas


<modulo>/<accion>[?parametro1=valor1][&parametro2=valor2][&parametro3=valor3]...
// Ejemplo de URI interna que nunca se muestra al usuario
articulo/permalink?ano=2006&tema=economia&titulo=sectores-actividad
// Ejemplo de URL externa que se muestra al usuario
http://www.ejemplo.com/articulos/economia/2006/sectores-actividad.html

112

Enlaces y sistema de enrutamiento

El sistema de enrutamiento utiliza un archivo de


configuracin especial, llamado routing.yml
articulo_segun_titulo:
url:
articulos/:tema/:ano/:titulo.html
param: { module: articulo, action: permalink }

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Adems, no se deben escribir los enlaces


directamente con etiquetas <a> (ya que de esta
forma no se estara utilizando el sistema de
enrutamiento) sino con un helper especial
<?php echo link_to(
'pincha aqui',
'articulo/permalink?tema=economia&ano=2006&titulo=sectores-actividad'
) ?>

113

Generadores

Generadores
Muchas aplicaciones web se reducen a una mera
interfaz de acceso a la informacin almacenada
en una base de datos.
Symfony automatiza la tarea repetitiva de crear
mdulos para manipular datos mediante el uso de
objetos Propel. Si el modelo de objetos est bien
definido, es posible incluso generar de forma
automtica la parte de administracin completa de
un sitio web.
En esta seccin se explican los 2 tipos de
generadores automticos incluidos en Symfony:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Scaffolding
Generador de la parte de administracin.
115

Generadores

Scaffolding:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

El "scaffolding" es una estructura bsica de acciones y


plantillas para poder realizar las operaciones CRUD
en una tabla de la base de datos.
El cdigo generado es mnimo, ya que solo es una
gua para seguir desarrollando. Se trata de la base
inicial que debe adaptarse para seguir los
requerimientos de lgica y presentacin de la
aplicacin.
El "scaffolding" se utiliza durante la fase de desarrollo
de la aplicacin para crear una acceso va web a la
base de datos, para construir un prototipo rpido o
para realizar automticamente el cdigo bsico de un
mdulo basado en una tabla de la base de datos.
116

Generadores

Administracin:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

La "administracin" es una interfaz avanzada para


manipular los datos y que se emplea en la parte de
gestin o administracin de las aplicaciones.
La principal diferencia con el "scaffolding" es que el
programador no modifica el cdigo generado para la
parte de administracin.
Mediante archivos de configuracin y herencia de
clases se puede personalizar y extender la parte de
administracin generada.
La presentacin de la interfaz es importante y por eso
incluyen opciones como el filtrado, la paginacin y la
ordenacin de datos.
La parte de administracin generada automticamente
con Symfony tiene calidad suficiente como para
entregarla al cliente formando parte de la aplicacin
117
que se le ha desarrollado.

Generadores

Scaffolding

Generando el scaffolding:

Para generar el scaffolding del mdulo article basado en la


clase Article del modelo
> symfony propel:generate-crud miaplicacion article Article

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

El mdulo generado incluye 3 vistas:


-

La vista list, que es la vista por defecto, muestra las filas de datos de
la tabla blog_article cuando se accede a la aplicacin mediante
http://localhost/miaplicacion_dev.php/article:

118

Generadores

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

La lista show. Todos los detalles de una fila de datos se


muestran en una nica pgina:

La edicin, edit:

119

Generadores

Elementos generados para las operaciones CRUD, en


miaplicacion/modules/article/

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

// En actions/actions.class.php
index
// Redirige a la accin "list"
list
// Muestra un listado de todas las filas de la tabla
show
// Muestra todas las columnas de una fila
edit
// Muestra un formulario para modificar la columnas de una
fila
update
// Accin que se llama en el formulario de la accin "edit"
delete
// Borra una fila
create
// Crea una nueva fila
// En templates/
editSuccess.php // Formulario para modificar una fila (vista "edit")
listSuccess.php // Listado de todas las filas (vista "list")
showSuccess.php // Detalle de una fila (vista "show")

120

Generadores

Iniciando el Scaffolding:

Otra opcin a la generacin est en "iniciar" para


comprobar que se puede acceder a los datos de la base de
datos.
Un scaffolding que solo ha sido iniciado es muy fcil de crear
y muy fcil de borrar una vez que se ha comprobado que
todo funciona correctamente.

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

> symfony propel:init-crud miaplicacion article Article

Las pginas resultantes son exactamente iguales que las


que tiene un scaffolding completamente generado.
La diferencia est en que los archivos generados se guardan
en la cache de la aplicacin (miproyecto/cache/miaplicacion/
prod/module/autoArticle/).

121

Generadores

Creando la parte de administracin de las


aplicaciones

Iniciando un mdulo de administracin:

Prviamente iniciaremos la aplicacin backend:


> symfony generate:app backend

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Los mdulos se generan en base a objetos Propel mediante


la tarea propel:init-admin:
> symfony propel:init-admin backend article Article

122

Generadores

Es accesible desde la direccin:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

http://miaplicacion.ejemplo.com/backend.php/article

123

Generadores
Los mdulos de una administracin solamente pueden ser
iniciados y nunca generados.
Cdigo generado:

Elementos de administracin generados automticamente, en


cache/backend/ENV/modules/article/:
-

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

// En actions/actions.class.php
create
// Redirige a "edit"
delete
// Borra una fila
edit
// Muestra un formulario para modificar la columnas de una fila
// y procesa el envo del formulario
index
// Redirige a "list"
list
// Muestra un listado de todas las filas de la tabla
save
// Redirige a "edit"
// En templates/
_edit_actions.php
_edit_footer.php
_edit_form.php
_edit_header.php
_edit_messages.php
_filters.php
_list.php
_list_actions.php
_list_footer.php
_list_header.php
_list_messages.php
_list_td_actions.php
_list_td_stacked.php
_list_td_tabular.php
_list_th_stacked.php
_list_th_tabular.php
editSuccess.php
listSuccess.php

124

Generadores

Conceptos bsicos del archivo de configuracin


generator.yml

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

Configuracin por defecto para la generacin de la


administracin, en
backend/modules/article/config/generator.yml
generator:
class:
param:
model_class:
theme:

sfPropelAdminGenerator
Article
default

125

Generadores

Configuracin completa tpica para el generador

generator:
class:
param:
model_class:
theme:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

fields:
author_id:

sfPropelAdminGenerator
Article
default
{ name: Article author }

list:
title:
List of all articles
display:
[title, author_id, category_id]
fields:
published_on: { params: date_format='dd/MM/yy' }
layout:
stacked
params:
|
%%is_published%%<strong>%%=title%%</strong><br /><em>by %%author%%
in %%category%% (%%published_on%%)</em><p>%%content_summary%%</p>
filters:
[title, category_id, author_id, is_published]
max_per_page:
2
edit:
title:
display:
"Post":
"Workflow":
fields:
category_id:
is_published:
created_on:
author_id:
published_on:
content:

Editing article "%%title%%"


[title, category_id, content]
[author_id, is_published, created_on]
{
{
{
{
{
{

params: disabled=true }
type: plain}
type: plain, params: date_format='dd/MM/yy' }
params: size=5 include_custom=>> Choose an author << }
credentials: }
params: rich=true tinymce_options=height:150 }

Para aprender fcilmente la sintaxis:


http://www.symfony-project.org/uploads/assets/sfAdminGeneratorRefCard.pdf

126

Bibliografia y referencias

Bibliografia y referencias

Symfony

The Definitive Guide to symfony:

Curso Framework Symfony - Jordi Llonch <jordi@laigu.net>

http://www.symfony-project.org/tutorial/1_1/my-first-projec

Symfony wiki

http://www.symfony-project.org/book/1_1/

Symfony tutorial: My first symfony project

http://www.symfony-project.org

http://trac.symfony-project.com/wiki

Cheat Sheets

http://trac.symfony-project.com/wiki/CheatSheets

128

También podría gustarte