Sie sind auf Seite 1von 23

Inicio Libros Tutoriales Eventos Foro Buscar

Cmo organizar bien un


proyecto Silex
Silex es un microframework para crear sitios y aplicaciones web con PHP. Si desarrollas
tus aplicaciones a mano y no quieres todava dar el salto a un framework grande como
Symfony, entonces Silex puede ser una buena solucin.

Este tutorial supone que ya tienes conocimientos bsicos de Silex (para ello, puedes leer
el manual oficial de Silex) y que has creado una aplicacin Silex siguiendo la estructura
habitual proporcionada por el Silex-Skeleton.

Adems, para simplificar los ejemplos de cdigo, se va a suponer que la aplicacin est
formada solamente por las siguientes cinco rutas:

Nombre URL Descripcin

portada / Portada del sitio


open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
eventos_index /eventos/ Portada de la seccin de eventos

eventos_show /eventos/{slug}/ Pgina de un evento especfico

foro_index /foro/ Portada de la seccin del foro

foro_show /foro/{id}/{slug}/ Pgina de una discusin del foro

La situacin inicial
Siguiendo el modelo tradicional de programacin de aplicaciones con Silex, todo el sitio
web se puede crear en un nico archivo PHP llamado index.php :

// archivo index.php
require_once __DIR__.'/../vendor/autoload.php';

$app = new Silex\Application();

$app->get('/eventos/{slug}/', function($slug) use($app) {


...
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
})->bind('eventos_show');

$app->get('/eventos/', function() use($app) {


...
})->bind('eventos_index');

$app->get('/foro/{id}/{slug}/', function($id, $slug) use($app) {


...
})->bind('foro_show');

$app->get('/foro/', function() use($app) {


...
})->bind('foro_index');

$app->get('/', function() use($app) {


...
})->bind('portada');

$app->run();

A finales de 2012 decidimos rehacer desde cero el sitio librosweb.es y optamos por
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
desarrollarlo con Silex. Como al principio no tenamos tantas secciones como ahora,
optamos por seguir esta forma de organizar el cdigo e incluimos todas las rutas y
controladores en un nico archivo.

Como era previsible, este modelo no escala bien en cuanto el sitio es de una
complejidad media. Al aadir todas las secciones del sitio, este archivo se convirti en
un monstruo inmanejable de miles de lneas de cdigo. As que en este tutorial te
contamos los tres mtodos alternativos que hemos utilizado para organizar bien el
cdigo de una aplicacin Silex mediana y las ventajas e inconvenientes de cada una.

Mtodo 1: Colecciones de controladores


El primer mtodo alternativo que utilizamos se basa en las colecciones de
controladores. El siguiente ejemplo muestra el nuevo cdigo de la aplicacin:

require_once __DIR__.'/../vendor/autoload.php';

$app = new Silex\Application();

$eventos = $app['controllers_factory'];

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
$eventos->get('/', function () use($app) {
...
})->bind('eventos_index');

$eventos->get('/{slug}/', function ($slug) use($app) {


...
})->bind('eventos_show');

$foro = $app['controllers_factory'];

$foro->get('/{id}/{slug}/', function($id, $slug) use($app) {


...
})->bind('foro_show');

$foro->get('/', function () use ($app) {


...
})->bind('foro_index');

$app->mount('/eventos', $eventos);
$app->mount('/foro', $foro);

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
$app->get('/', function() use($app) {
...
})->bind('portada');

$app->run();

Cada seccin de la aplicacin (foro y eventos) se agrupa en una coleccin de


controladores mediante el servicio $app['controllers_factory'] y despus se
incluyen en la aplicacin con el mtodo mount() .

La primera ventaja es que puedes aplicar un mismo prefijo a todas las rutas
relacionadas. Por eso en el cdigo anterior, la ruta foro_index no es /foro sino
simplemente / , ya que el prefijo /foro se incluye automticamente al montar la
coleccin de controladores.

La segunda ventaja es que ahora resulta muy sencillo reordenar las rutas de la
aplicacin, ya que para ello simplemente debes cambiar el orden de las instrucciones
mount() . Por ltimo, las colecciones tambin permiten aplicar fcilmente un middleware
a un conjunto de rutas, como muestra el siguiente ejemplo que restringe el acceso a la
seccin del foro:

// ...
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
$app = new Silex\Application();

$foro = $app['controllers_factory'];
$foro->get('/{id}/{slug}/', ...)->bind('foro_show');
$foro->get('/', ...)->bind('foro_index');

// restringir el acceso a todas las rutas del foro


$foro->before(function() use($app) {
if (!$app['security']->isGranted('ROLE_ADMIN')) {
// ...
}
});

$app->mount('/foro', $foro);

// ...

La principal desventaja de este mtodo es que no mejora mucho la situacin inicial.


Como todo el cdigo sigue estando en un nico archivo, resulta difcil manejarlo. Una
posible solucin consiste en colocar el cdigo de cada seccin en su propio archivo e
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
importarlo despus dentro de la instruccin mount() :

// archivo foro.php
$foro = $app['controllers_factory'];
$foro->get('/{id}/{slug}/', ...)->bind('foro_show');
$foro->get('/', ...)->bind('foro_index');

return $foro;

// archivo index.php
$app = new Silex\Application();

// ...
$app->mount('/foro', include __DIR__.'/foro.php');

$app->run();

Ahora el cdigo s que est dividido en varios archivos ms pequeos y manejables. El


nico problema de esta solucin es que el uso del include la hace poco elegante. Los
dos mtodos que se muestran a continuacin consiguen un resultado similar pero de
forma mucho ms profesional.

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Mtodo 2: Controladores en clases PHP
normales
Este segundo mtodo es similar al explicado en la seccin anterior, pero se basa en
crear una clase PHP para cada seccin del sitio. Dentro de esa clase, se define un
mtodo para cada ruta/controlador de esa seccin. El siguiente ejemplo muestra la
clase para la seccin del foro:

// archivo src/Controllers/ForoController.php
namespace Librosweb\Controllers;

use Silex\Application;

class ForoController
{
public function show(Application $app, $id, $slug)
{
...
}

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
public function index(Application $app)
{
...
}
}

Aunque puedes llamar como quieras a estas clases y puedes guardarlas en cualquier
sitio, nuestra recomendacin para organizar mejor el cdigo es que guardes estas clases
en el directorio Controllers y que normalices sus nombres para que siempre acaben
en Controller .

Si necesitas acceder a la aplicacin o a la peticin del usuario dentro de un controlador,


slo tienes que aadir respectivamente Application $app o Request $request en la
declaracin del mtodo y Silex los inyectar automticamente.

Una vez creadas todas estas clases, debes modificar el anterior archivo index.php para
definir en l solamente las rutas de la aplicacin, no los controladores:

require_once __DIR__.'/../vendor/autoload.php';

$app = new Silex\Application();

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
$app->get('/eventos/{slug}/', 'Librosweb\Controllers\EventosController::s
how')
->bind('eventos_show');
$app->get('/eventos/', 'Librosweb\Controllers\EventosController::index')
->bind('eventos_index');

$app->get('/foro/{id}/{slug}/', 'Librosweb\Controllers\ForoController::sh
ow')
->bind('foro_show');
$app->get('/foro/', 'Librosweb\Controllers\ForoController::index')
->bind('foro_index');

$app->get('/', function() use($app) {


...
})->bind('portada');

$app->run();

Cada ruta define su controlador asociado mediante la notacin Clase::metodo . No


confundas la notacin :: con el operador :: de PHP que se utiliza para acceder a los
mtodos estticos de las clases, ya que no tienen nada que ver.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
La principal ventaja de este mtodo es que el cdigo se divide en varias clases
pequeas y manejables. Adems, el rendimiento de la aplicacin no se resiente porque
cuando el usuario realiza una peticin, solamente se instancia la clase asociada a esa
ruta.

La principal desventaja es que si tienes muchas rutas, el archivo index.php de nuevo


es demasiado grande y se vuelve difcil de manejar.

Mtodo 3: Controladores en clases de tipo


ControllerProvider
Esta ltima forma de organizar el cdigo de las aplicaciones Silex combina la mayor
parte de las ventajas de los otros dos mtodos y tiene muy pocos inconvenientes. Por
eso creemos que es la mejor forma de organizar el cdigo de las aplicaciones Silex
medianas y es el mtodo que utilizamos actualmente para el cdigo fuente de
librosweb.es.

El funcionamiento de este mtodo se basa en el uso de los proveedores de


controladores de Silex. Cada seccin del sitio web se convierte en una clase PHP
especial y despus se montan todas ellas con el mtodo mount() de la aplicacin.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Observa en primer lugar el cdigo completo del archivo index.php y cmo se importan
las dos clases:

require_once __DIR__.'/../vendor/autoload.php';

$app = new Silex\Application();

$app->mount('/eventos', new Librosweb\Controllers\EventosController());


$app->mount('/foro', new Librosweb\Controllers\ForoController());

$app->get('/', function() use($app) {


...
})->bind('portada');

$app->run();

Las clases EventosController y ForoController son similares a las clases mostradas


en la seccin anterior. La diferencia es que estas clases deben implementar la interfaz
ControllerProviderInterface :

// archivo src/Controllers/ForoController.php
namespace Librosweb\Controllers;
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
use Silex\Application;
use Silex\ControllerProviderInterface;

class ForoController implements ControllerProviderInterface


{
// ...
}

La interfaz ControllerProviderInterface obliga a definir un mtodo llamado


connect() que devuelve la coleccin de controladores creada por esta clase. As que el
cdigo completo de la clase ForoController de este ejemplo podra ser el siguiente:

// archivo src/Controllers/EventosController.php
namespace Librosweb\Controllers;

use Silex\Application;
use Silex\ControllerProviderInterface;

class ForoController implements ControllerProviderInterface


{

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
public function connect(Application $app)
{
$controllers = $app['controllers_factory'];

$controllers->get('/{id}/{slug}/', function($id, $slug) use($app)


{
...
})->bind('foro_show');

$controllers->get('/', function() use($app) {


...
})->bind('foro_index');

return $controllers;
}
}

Una ltima variante de este mtodo consiste en indicar un callback para cada
controlador, en vez de escribir todo su cdigo mediante una funcin annima. As que el
siguiente ejemplo muestra el cdigo completo tal y como realmente lo utilizo en mis
aplicaciones:
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
// archivo src/Controllers/EventosController.php
namespace Librosweb\Controllers;

use Silex\Application;
use Silex\ControllerProviderInterface;

class ForoController implements ControllerProviderInterface


{
public function connect(Application $app)
{
$controllers = $app['controllers_factory'];

$controllers
->get('/{id}/{slug}/', array($this, 'foroShow'))
->bind('foro_show')
;

$controllers
->get('/', array($this, 'foroIndex'))
->bind('foro_index')
;
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
return $controllers;
}

public function foroIndex(Application $app)


{
...
}

public function foroShow(Application $app, $id, $slug)


{
...
}
}

Por ltimo, este mtodo tambin permite aplicar fcilmente un middleware a toda la
coleccin de controladores. As es muy sencillo por ejemplo restringir el acceso a una
parte de la aplicacin:

// archivo src/Controllers/EventosController.php
namespace Librosweb\Controllers;

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
use Silex\Application;
use Silex\ControllerProviderInterface;

class ForoController implements ControllerProviderInterface


{
public function connect(Application $app)
{
$controllers = $app['controllers_factory'];

// restringir el acceso a todas las rutas del foro


$controllers->before(function() use($app) {
if (!$app['security']->isGranted('ROLE_ADMIN')) {
// ...
}
});

$controllers->get('/{id}/{slug}/', ...)->bind('foro_show');
$controllers->get('/', ...)->bind('foro_index');

return $controllers;
}
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
}

Las ventajas de este mtodo son que el archivo index.php es pequeo y manejable,
que resulta muy sencillo montar los controladores con un prefijo comn ( /foro ,
/eventos , etc.) y que las rutas de la aplicacin se pueden reordenar fcilmente. Adems,
el cdigo de cada seccin del sitio se define en su propia clase, tambin pequea y
manejable, que incluye tanto las rutas como los controladores de esa seccin.

La nica desventaja notable que he encontrado a este mtodo es que cuando el


usuario realiza una peticin, Silex instancia todas y cada una de las clases de tipo
ControllerProviderInterface de la aplicacin y no solamente la que est asociada
con la ruta solicitada por el usuario. Esto puede penalizar ligeramente el rendimiento de
la aplicacin cuando se divide el cdigo en muchas clases diferentes.

Referencias tiles
La mejor forma de aprender a organizar las aplicaciones medianas con Silex consiste en
ver el cdigo fuente de alguna aplicacin real. Como el cdigo de librosweb.es no es
pblico, enlazamos a continuacin el cdigo de dos aplicaciones Silex medianas que
estn programadas de una manera muy similar:

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Bolt, gestor de contenidos que organiza su cdigo siguiendo el mtodo 2 (ver
ejemplo).

GitList, clon del sitio GitHub y que organiza su cdigo siguiendo el mtodo 3 (ver
ejemplo).

Comentarios
2 Comentarios LibrosWeb
1 Acceder

Ordenar por los mejores


Recomendar Compartir

nete a la conversacin...

Luciano Rodriguez hace un ao


Buenas, los link al ejemplo de bolt y gitlist estn caidos. Gracias.
Responder Compartir

Javier Eguiluz Moderador > Luciano Rodriguez hace un ao


Gracias por avisar! Acabo de corregir esos enlaces.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Responder Compartir

TAMBIN EN LIBROSWEB

Preparando tus bocetos sin el Lorem Ipsum El nuevo elemento de HTML5 para crear imgenes
1 comentario hace un ao responsive
Higinio Fuentes Gracias!Que bien que lo haya Ud. 2 comentarios hace un ao
puesto a disposicion. Es una idea muy practica ya que Rosevelt Barahona eso tendria que ser con media
es verdad, el cliente se distrae con el queries en el css.

Trucos y ejemplos de configuracin del archivo Los cdigos de estado de HTTP


htaccess de Apache 1 comentario hace un ao
6 comentarios hace un ao Martha Villacis Excelente post. Felicitaciones muy
Alan Toledo posiblemente no tengas un certificado bueno.
SSL

Suscrbete d Aade Disqus a tu sitio web Privacidad

Fecha de publicacin
8 de noviembre de 2013
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
ETIQUETAS POPULARES
composer css diseo html javascript php programacin sistemas symfony

SUSCRBETE GRATIS

RSS Todos los tutoriales

RSS Tutoriales de diseo

RSS Tutoriales de programacin

3.756
2006-2017 LibrosWeb.es Contacto Novedades Condiciones Privacidad

das online

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com

Das könnte Ihnen auch gefallen