manual表示中间件之前的>可以像这样将路由器短路:
$app->before(function (Request $request) {
if (...) {
return new RedirectResponse('/login');
}
});
我的实现如下:
$app->post( '/push/{id}', function( $id, Request $request, Application $app ) {
$app['post.data'] = $request->request->all();
})
->assert( 'id', '[a-f\d]{24}' )
->before(function( Request $request, Application $app ){
$item = $app['mongodb.maps']->findOne([
'_id' => new MongoId( $request->get('id') )
]);
if( !$item ) {
return new RedirectResponse( 'http://test.com', 301 );
} else $app['mapdata'] = $item;
})
->after(function( Request $request, Response $response, Application $app ){
if( !isset( $app['post.data'] ) ) {
return new RedirectResponse( 'http://google.com', 301 );
}
})
->after(function( Request $request, Response $response, Application $app ){
if( !isset( $app['post.data'] ) ) {
return new RedirectResponse( 'http://google.com', 301 );
}
});
如果assert()成功,则before事件获取必要的数据,然后将其传递给全局变量。因为我返回一个重定向,它会跳过路线,但随后会执行after事件。在之后的事件中,我检查是否存在应该在路线中创建的后期数据,因为没有执行该路线会产生错误,即post.data键未被定义。我现在在那里抛出一个重定向,最后重定向。但是我必须在每个after()方法中执行此操作,否则我会得到键未定义的错误。 (它永远不会重定向到test.com)
这是正常的吗?是否有更稳固的方式退出之前并跳过所有其他呼叫?
答案 0 :(得分:2)
作为documentation states(强调我的):
如果之前的中间件返回一个Response对象,请求处理将被短路(下一个中间件将不会运行,也不会运行路由回调),并且Response会立即传递给after中间件< /强>
所以是的,这是正常行为。
我看不到一个简单的方法来做你想做的事。不考虑太多选项可能不是使用默认的after
中间件,而是扩展 Silex \ Application 并创建自定义after
中间件,检查参数是否存在:
<?php
use Symfony\Component\HttpFoundation\RedirectResponse;
use Silex\Application as SilexApp
class MyApp extends SilexApp
{
public function myAfter($callback, $priority = 0)
{
$app = $this;
$this->on(KernelEvents::RESPONSE, function (FilterResponseEvent $event) use ($callback, $app) {
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
return;
}
// Make sure that the callback is called when the pre conditions are met
if (!empty($app['post.data'])) {
$response = call_user_func($app['callback_resolver']->resolveCallback($callback), $event->getRequest(), $event->getResponse(), $app);
if ($response instanceof Response) {
$event->setResponse($response);
} elseif (null !== $response) {
throw new \RuntimeException('An after middleware returned an invalid response value. Must return null or an instance of Response.');
}
}
else {
$event->setResponse(new RedirectResponse('http://google.com', 301));
}
}, $priority);
}
}