我有一个采取参数的动作,路线看起来像这样:
/ CS / {ID}
它是Cassette控制器中的individualAction.
有时,有一个异常500内部服务器错误 – NoResultException – 这是预期的行为.
我想重定向到另一个控制器动作,editAction,当发生这种情况时,路由是这样的:
/ CS / {ID} /编辑
它需要特定于控制器,因为我想用不同的控制器动作重复这一点.它还需要保持原始行动的论点.
我一直在调查事件监听器,但我不确定这是否过度,我正在努力找出如何使它们特定于行动 – 如果这是更好的解决方案,我很乐意将代码保留在控制器中.
最佳答案 当抛出异常时,EventListener最适合更改应用程序的压缩.
使用类似的东西:
<?php
namespace AppBundle\EventListener;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\Routing\RouterInterface;
use Doctrine\ORM\NoResultException;
class ExceptionResponseListener
{
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
/**
* @param GetResponseForExceptionEvent $event
*/
public function onKernelResponse(GetResponseForExceptionEvent $event)
{
$request = $event->getRequest();
$routeName = $request->get('_route');
$exception = $event->getException();
// Restrict the route by adding a check on the route name
// Or a pattern of route names (!strpos($routeName, '_show'))
// Or for many routes: (!in_array($routeName, ['xxx_show', ...]
// Or the _controller: $request->get('_controller')
// Output something like: "AcmeBundle\\Controller\\DefaultController::showAction"
if ('expected_route_name' !== $routeName) {
return;
}
// Retrieve your param
$params = $request->get('_route_params');
if ($exception instanceof NoResultException) {
// Create a redirection to the edit route
$response = new RedirectResponse(
$this->router->generate('your_edit_route', array('id' => $params['id']))
);
$event->setResponse($response);
}
}
}
并将其注册为服务:
services:
# ...
acme.kernel.listener.exception_listener:
class: AppBundle\EventListener\ExceptionResponseListener
tags:
- {name: kernel.event_listener, event: kernel.exception, method: onKernelResponse}
arguments: ['@router']
另一个简单的替代方法是直接在您的方法中进行预期操作的转发/重定向,而不是抛出异常.