Silex te permite ejecutar código, que cambie el comportamiento predefinido de Silex, en diferentes etapas durante la manipulación de una petición a través de semiwares:
Los semiwares de la aplicación sólo se ejecutan en la petición «maestra».
Un semiware before de la aplicación te permite ajustar la Petición antes de ejecutar el controlador:
$app->before(function (Request $request) {
// ...
});
De manera predeterminada, el semiware se ejecuta después del enrutado y la seguridad.
Si quieres que tu semiware se ejecute incluso si se lanza una excepción temprana (en un error 404 o un error 403, por ejemplo), entonces, necesitas registrarlo como un evento temprano:
$app->before(function (Request $request) {
// ...
}, Application::EARLY_EVENT);
Naturalmente, en este caso, el enrutado y la seguridad no se habrán ejecutado, y no tendrás acceso a la región, la ruta actual, o al usuario de seguridad.
Nota
El semiware before es un evento registrado en el evento request de Symfony.
Un semiware after de la aplicación te permite ajustar la Respuesta antes de enviarla al cliente:
$app->after(function (Request $request, Response $response) {
// ...
});
Nota
El semiware after es un evento registrado en el evento request de Symfony.
Un semiware finish de la aplicación te permite ejecutar tareas después de enviar la Respuesta al cliente (tal como enviar correo electrónico o llevar la bitácora):
$app->finish(function (Request $request, Response $response) {
// ...
// Atención: Las modificaciones a la Petición o a la Respuesta serán omitidas
});
Nota
El semiware finish es un evento registrado en el evento terminate de Symfony.
El semiware route se añade a las rutas o colecciones de rutas y sólo se desencadena al concordar la ruta correspondiente. También los puedes apilar:
$app->get('/somewhere', function () {
// ...
})
->before($before1)
->before($before2)
->after($after1)
->after($after2)
;
Un semiware de ruta before se lanza justo antes de la retrollamada a la ruta, pero después del semiware before de la aplicación:
$before = function (Request $request) use ($app) {
// ...
};
$app->get('/somewhere', function () {
// ...
})
->before($before);
Un semiware after de la ruta se lanza justo después de la retrollamada a la ruta, pero antes del semiware after de la aplicacións:
$after = function (Request $request, Response $response) use ($app) {
// ...
};
$app->get('/somewhere', function () {
// ...
})
->after($after);
Puedes añadir tantos semiwares como quieras, en cuyo caso serán lanzados en el mismo orden en que los añadiste.
Puedes controlar explícitamente la prioridad de tu semiware pasando un argumento adicional a los métodos suscriptores:
$app->before(function (Request $request) {
// ...
}, 32);
Para tu comodidad, dos constantes te permiten registrar un evento tan temprano o tan tarde como sea posible:
$app->before(function (Request $request) {
// ...
}, Application::EARLY_EVENT);
$app->before(function (Request $request) {
// ...
}, Application::LATE_EVENT);
Si un semiware before regresa un objeto Respuesta, se cortocircuita el controlador que está manejando la Petición (el siguiente semiware no será ejecutado, ni la retrollamada a la ruta), y la Respuesta se pasa al siguiente semiware after:
$app->before(function (Request $request) {
// redirige al usuario al formulario de acceso si el recurso accedido está protegido
if (...) {
return new RedirectResponse('/login');
}
});
Nota
Si un semiware before no devuelve una Respuesta o regresa null, se lanza una RuntimeException.