Symfony2在内核请求事件中抛出404

Nic*_*ick 1 php events symfony

我可能会以完全错误的方式进行操作,但是我有一个onKernelRequest事件设置,该事件设置获取当前域(单个应用程序上的多个站点),查询缓存/数据库并将其存储在服务中,以供其他控制器/服务使用。这很完美。

现在,如果找不到域,我想抛出404错误。通常,我只是在控制器中执行以下操作:

throw new NotFoundHttpException('Not found!');
Run Code Online (Sandbox Code Playgroud)

但这会导致生产中出现未捕获的异常,因此我假设由于事件的优先级(31)。

PHP Fatal error:  Uncaught exception 'Symfony\Component\HttpKernel\Exception\NotFoundHttpException' with message 'Not found!'
Run Code Online (Sandbox Code Playgroud)

我当前的代码(为清楚起见,删除了逻辑),请注意,我使用JMSDiExtraBundle配置服务。

/**
 * @Service
 */
class CurrentDomainListener
{
    /**
     * @Observe("kernel.request", priority=31)
     */
    public function onKernelRequest(GetResponseEvent $event)
    {
        // find domain in cache/database...

        if (!$domain) {
            throw new NotFoundHttpException('Not found!');
        }

        // store domain in service...
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,当域不存在时显示404错误的最佳方法是什么?

Bar*_*ada 6

不知道这是否是最优雅的解决方案,但是我遇到了同样的问题,这对我有用:

引发并ExceptionListener捕获异常时,它将异常添加到请求属性并重播请求。这将导致再次通知侦听器,并且由于与第一次相同的原因,它们将引发另一个异常。

我通过检查侦听器的请求中是否未设置异常来解决(解决此问题):

public function onKernelRequest(GetResponseEvent $event)
{
    $request = $event->getRequest();
    if ($request->attributes->has('exception')) {
        return;
    }

    // ...
    if ($somethingWasWrong) {
        throw new NotFoundHttpException();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果已经抛出异常,就不会检查失败的条件,并且可以适当地处理异常。

编辑:我调查了Symfony侦听器,他们检查当前请求是否是主请求:

if (!$event->isMasterRequest()) {
    return;
}
Run Code Online (Sandbox Code Playgroud)