StackPHP: Ejecución de una pila de HttpKernelInterface

Posted by victor on June 9th, 2013
symfony2-logoHace unas semanas leía un artículo muy interesante titulado "HttpKernel middlewares" de  Igor Wiedler acerca de la importancia de HttpKernelInterface y de como se puede crear una pila de HttpKernel que se ejecuten en cadena. Por si esta interfaz no te suena, pertenece al componente HttpKernel de Symfony2 y es la parte central del framework. Digamos que es la interfaz que cumplen las clases que desean gestionar peticiones y que usan componentes de Symfony2. Para entender la importancia de esta interfaz, hay que remontarse a la especificación Rack de Ruby que define la forma en la que un servidor web puede interactuar con una aplicación Ruby. Mediante Rack, cualquier aplicación que cumpla la interfaz puede interactuar con un servidor web. En PHP, la interfaz se llama SAPI -Server Application Programming Interface- y dispone de varias en función del entorno y del servidor web: CLI, CGI-FCGI, ISAPI (IIS de Microsoft) etc... Puedes obtener el nombre de la interfaz SAPI con php_sapi_name(). A diferencia de Rack, la interfaz de PHP es demasiado plana: $_GET, $_POST y $_SERVER. Sería más fácil e intuitivo trabajar con objetos y de eso se encarga HttpKernelInterface. Esta interfaz entrega un objeto de tipo Request, que es una representación de los datos más adecuada para trabajar y con muchas facilidades. Como salida, espera un objeto tipo Response que representaría la respuesta HTTP. La desventaja HttpKernelInterface con respecto a Rack es que no existe una especificación. HttpKernelInterface pertenece a Symfony2 y no forma parte del core de PHP, pero los principales componentes de este framework se están convirtiendo en un estádar de facto para construir otros framework como Laravel, Drupal o Magento.

StackPHP

La idea que propone Igor Wiedler es la ejecución en cadena de componentes que cumplen esta interfaz, al estilo de como funcionaban los filtros de Symfony 1.x. Se trata de que en cada etapa, se pueden realizar acciones durante la ida y la vuelta de la ejecución. Acciones como logger, debug, autenticación, uso de https etc... La ejecución de este tipo de stack en framework como Silex o Laravel es de gran utilidad y para facilitar la construcción de estas pilas existe un proyecto llamado stackphp que simplifica enormemente la creación de estas pilas:
// Ejemplo con Silex:
$app = new Silex\Application();

$stack = (new Stack\Builder()) ->push('Stack\Session') ->push('Symfony\Component\HttpKernel\HttpCache\HttpCache', new Store(__DIR__.'/cache')); $app = $stack->resolve($app);
Además del builder, en Stackphp han desarrollado varios componentes Stack/Session, Stack/UrlMap y Stack/OAuth.

Un ejemplo

En Github @acleon ha publicado un ejemplo que permite añadir al stack datos de geolocalización de la IP. Los datos son insertados en las cabeceras de peticiones. Usarlo es sencillo y solo requiere incluirlo en el StackPHP:
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;

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

$app = new Silex\Application();

...
$stack = (new Stack\Builder())
    ->push('Ducks\Stack\GeoIp');

...
  Ruby: Rack Builder.

Comments

comments powered by Disqus