symfony2:挂钩 NotFoundHttpException 以进行重定向 [英] symfony2: hook into NotFoundHttpException for redirection
问题描述
我目前正在将我们的项目迁移到 symfony2.在我们当前的代码库中,我们有一种机制允许我们在数据库表中定义路由.我们基本上指定了一个与请求 URL 匹配的正则表达式,并指定用户应该重定向到的 URL.这种重定向在抛出 404 之前作为最后的手段"起作用.这样,这些重定向永远不会覆盖匹配现有操作的 URL,并且匹配会延迟完成,只有在抛出 404 的情况下.
I'm currently migrating our project to symfony2. In our current codebase, we have a mechanism that allows us to define routings in a database table. We basically specify a regex the request URL gets matched against, and specify the URL the user should be redirected to. This redirecting works as a "last resort" right before throwing the 404. That way, these redirects never overwrite URLs that match existing actions and the matching is done lazily, only in case a 404 would have been thrown.
有没有办法挂钩到 Symfony 的事件模型并监听 NotFoundHttpException 来做到这一点(例如,如果 URL 匹配某些正则表达式,则发出 301/302 重定向,而不是让 404 低谷)?
Is there a way to hook into Symfony's event model and listen for the NotFoundHttpException to do exactly that (e.g. issuing a 301/302 redirect if the URL matches some regex, instead of letting the 404 trough)?
推荐答案
正如您从 this cookbook page,每当抛出异常时都会触发kernel.exception"事件.我不知道 NotFoundHttpException 有特定事件,但我建议为所有异常创建自己的侦听器服务,然后在服务中检查异常类型并添加自定义逻辑.
As you can see from this cookbook page, a "kernel.exception" event is fired whenever an exception is thrown. I'm not aware of there being a specific event for a NotFoundHttpException but I'd suggest creating your own listener service for all exceptions and then checking within the service for the type of exception and adding your custom logic.
(注意:我还没有测试过这个,但它至少应该让你知道如何实现这一点.)
(Note: I haven't tested this, but it should at least give you an idea of how this can be achieved.)
配置
acme.exception_listener:
class: Acme\Bundle\AcmeBundle\Listener\RedirectExceptionListener
arguments: [@doctrine.orm.entity_manager, @logger]
tags:
- { name: kernel.event_listener, event: kernel.exception, method: checkRedirect }
监听服务
namespace Acme\Bundle\AcmeBundle\Listener;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Doctrine\ORM\EntityManager;
class RedirectExceptionListener
{
/**
* @var \Doctrine\ORM\EntityManager
*/
protected $em;
protected $logger;
function __construct(EntityManager $em, LoggerInterface $logger)
{
$this->em = $em;
$this->logger = $logger;
}
/**
* @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
*/
public function checkRedirect(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
if ($exception instanceof NotFoundHttpException) {
// Look for a redirect based on requested URI
// e.g....
$uri = $event->getRequest()->getUri();
$redirect = $this->em->getRepository('AcmeBundle:Redirect')->findByUri($uri);
if (!is_null($redirect)) {
$event->setResponse(new RedirectResponse($redirect->getUri()));
}
}
}
}
这篇关于symfony2:挂钩 NotFoundHttpException 以进行重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!