Hero

Enrutamiento en Silex

Mayo 09, 2014

enzo
PHP
Programación
Silex

Siguiendo con la continuación de la entrada de blog ¿Qué es Silex? Hoy vengo a hablarles del proceso de enrutamiento para este micro framework.

Para las personas que se enfrentan por primera ves a un framework que implementa en el patron de diseño MVC es el aspecto de tener que crear clases para manejo de eventos y controladores para dichos evento y lo que implica en crear una estructura de directorios para que el framework pueda encontrar los archivos apropiados.

Con Silex este proceso se simplifica, en el sentido de que para Silex solo implementa los controladores un archivo php es una aplicación sencilla o varios archivos podrían manejar una aplicación mediana; dejando por fuera el Modelo y la vista.

En el proceso de enrutamiento Silex hace uso de closures de PHP, puedes encontrar una explicación detallada en la entrada de blog Funciones anónimas en PHP.

  1. Hola Mundo en Silex.

Buenos ya todos estarán esperando este bendito y mágico ejemplo para iniciar a entender como funciona Silex, pues bien veamos el ejemplo en acción.

<?php

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

$app = new Silex\Application();

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

return $app->escape('Hola Mundo');
});
 
$app->run();

El código anterior lo debemos almacenar en un archivo con el nombre que deseemos que sea interpretado como código PHP por ejemplo index.php, aunque parezca extraño el programa anterior por sencillo que parezca es una aplicación completa de Silex. Veamos un poco que realiza nuestro ejemplo.

Primero se cargar las clases de autoload de Silex, que permitirá que las clases que necesitemos se carguen a medida que lo vayamos necesitando en nuestra aplicación.

Luego de crear nuestra objeto de aplicación Silex en la variable $app en una sola instrucción le indicamos en el primero parámetro del método get al Framework que registre en el HttpKernel la ruta /hola e inmediatamente le indicamos que controlador se ejecutara al tratar de ingresar esa ruta, esta operación se realiza mediante la función anónima enviada como segundo parámetro.

Para ejecutar ejecutar esta ruta y su controlador solo debemos ingresar en nuestro navedor una dirección similar a http://localhost:8080/index.php/hola

Si se ve el código del controlador hace uno del objeto $app que en enviado a la función usando la directiva use de las funciones anonimas y de esta forma burlar posible erores de ambito de las variables o tener que declarar variables globales.

Con esto habremos implemtando con éxito nuestra primera ruta de tipo GET.

  1. Ruta con variables dinámicas.

ya que hemos podido ejecutar con existo nuestro primer ejemplo, veamos como podemos extender nuestro controlador habilitando para recibir parámetros como se muestras a continuación.

<?php

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

$app = new Silex\Application();

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

return $app->escape('Hola ' . $mae . '!');
});
 
$app->run();

Dentro del primer parámetro del método get le indicamos con los caracteres especiales {mae} que deseamos obtener opcionalmente por medio de la URL un parámetro, si este parámetro es proporcionado se pasara a la función anónima en la variable $mae y que luego es utilizada para cambiar la salida de nuestra ruta.

Para ejecutar el anterior código solo debemos ejecutar en nuestro browser http://localhost:8080/index.php/hola/enzo e imprimirá el texto Hola enzo!

Para los que se preguntan que es mae, es una forma en costa rica de decir buddy.

Si solo tenemos esta ruta registrada en nuestra aplicación y ejecutamos la URL del anterior ejemplo http://localhost:8080/index.php/hola obtendremos un error 404, porque no tendremos una ruta que corresponda a este llamado.

Dentro de nuestra aplicación podemos agregar tantas rutas como deseemos, pero el order en que creemos las rutas es importante porque la primera ruta que cumpla con el patron esta sera ejecutada.

  1. Ruta con variables dinámicas y valores por defecto.

Ahora que tal si queremos mantener la mista ruta, pero deseamos colocar valores por defecto para evitar que nuestros usuarios obtengan un error 404 si no ingresaron los parámetros, bueno para ellos nuestra app solo necesita un cambio pequeño.

<?php

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

$app = new Silex\Application();

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

return $app->escape('Hola ' . $mae . '!');
})
->value('mae', 'MAE'); 
 
$app->run();

Lo único que hemos hecho es asociar un valor por defecto a nuestra variable dinámica {mae} en este caso si visitamos la URL http://localhost:8080/index.php/hola obtendremos el texto Hola MAE! que es nuestro valor por defecto.

  1. Otros métodos HTTP.

Los ejemplos anteriores han sido métodos GET, veamos como se puede crear un método POST

<?php

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; 
 
require_once __DIR__.'/../vendor/autoload.php';

$app = new Silex\Application();

$app->post('/encuesta', function(Request $request) use ($app) {
   $customer_email = $request->get('customer_email');
   mail('encuensta@yoursite.com', '[YourSite] Encuenta', $customer_email);

    return new Response('Gracias por llenar la encuenta!', 201);
});
 
$app->run();

En el ejemplo anterior incluimos la ruta de dos clases, para que por medio del autoloader las clases sean cargadas cuando se requerido.

Ahora llamamos al método post de la aplicación Silex que tiene una URL del mismo modo que el metodo get, con la diferencia que ahora nuestra función anónima ahora recibe por parámetro el objeto de tipo Request, el cual contendrá toda la info enviada por el browser mediante POST y otros datos del request HTTP; esta respuesta pudo ser mediante un formulario que sería la forma mas tradicional, pero también pude hacerse metiendo un ajax.

Al finalizar usando el objeto Response para proveer una respuesta a nuestros usuarios y al mismo tiempo devolver un estado en nuestra respuesta con el status 201 que indica Created el cual es una respuesta adecuando a un llamado post en caso de que no se haya presentado algún error.

Si deseamos implementar una API tipo REST, podemos llamar los métodos $app->put(), y $app->delete()

Para finalizar podemos dejar que la aplicación detecte las solicitudes REST solicitados por nuestros clientes, usando el método $app->match() como vemos a continuación.

use Symfony\Component\HttpFoundation\Request;
 
$app->match('/blog', function (Request $request) {
    // ...
});

Todos los métodos que usen la ruta asignada serán ejecutadas por nuestro closure, depende de nosotros que revisemos el contenido del $request para realizar las operación deseadas.

También podemos agrupar los match para que solo funciones con ciertas solicitudes REST como se muestra en el siguiente código:

use Symfony\Component\HttpFoundation\Request;
 
$app->match('/blog', function (Request $request) {
    // ...
})->method('PUT|POST');

En código anterior solo funcionara para las solicitudes REST PUT y POST.

Espero que haya sido de su agrado.

Recibe consejos y oportunidades de trabajo 100% remotas y en dólares de weKnow Inc.