无法阻止Symfony 3控制器中的错误跟踪


Unable to block error traces in a Symfony 3 controller

我正在研究Symfony'Component'Debug'Debug。据我所知,AppKernel的构造函数可以接受第二个参数来定义是否使用调试模式(true/false)。我实际上不明白的是Debug::enable()的用法和互补性,正如Symfony Github官方存储库上的app_dev.php所示。

例如,我试图在控制器上抛出一个Exception以查看效果,并在app_dev.php中评论了Debug::enable();,但我总是看到错误页面。

为什么尽管注释掉了Debug::enable();,我仍然看到错误痕迹?

简短解释

Debug::enable()方法注册一个回退错误处理程序,如果应用程序无法处理错误,则会调用该程序。

当内核在$debug标志设置为true的情况下启动时,您看到的错误页面是应用程序错误处理(由异常侦听器实现)的结果。将标志设置为false以禁用堆栈跟踪。如果你只是在测试之后,你也可以在开发中禁用错误页面。

Debug组件显示的页面不如异常侦听器提供的页面好,但它比PHP页面好。

详细解释

前端控制器调用应用程序内核:

$kernel = new AppKernel('dev', true);
$response = $kernel->handle(Request::createFromGlobals());

应用程序内核引导自己,创建容器并调用http内核来处理请求:

public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
    if (false === $this->booted) {
        $this->boot();
    }
    return $this->getHttpKernel()->handle($request, $type, $catch);
}

http内核将使用事件调度器来触发某些事件(kernel.requestkernel.responsekernel.exception等)。当在处理请求时抛出异常时,http内核将捕获它并触发kernel.exception事件:

// the following code is simplified to show the point
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
    try {
        return $this->handleRaw($request, $type);
    } catch ('Exception $e) {
        return $this->handleException($e, $request, $type);
    }
}
private function handleException('Exception $e, $request, $type)
{
    $event = new GetResponseForExceptionEvent($this, $request, $type, $e);
    $this->dispatcher->dispatch(KernelEvents::EXCEPTION, $event);
    // ...
}

默认情况下,在Symfony Standard Edition中注册的侦听器之一是Symfony'Component'HttpKernel'EventListener'ExceptionListener。它负责呈现漂亮的错误页面。

但是,它只会处理http内核中处理请求时抛出的异常。因此,如果这个调用之外出现任何问题,都不会得到处理(请查看上一个代码示例中的catch博客)。

这就是Debug组件的作用所在。Debug::enable()方法注册了一个错误处理程序、一个异常处理程序和一个特殊的类加载器。您可以在没有http内核的任何PHP项目中使用它。它是一种回退错误处理程序,如果您的应用程序无法处理错误,就会调用它。它与内核中的$debug构造函数参数没有关系。