我正在研究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.request
、kernel.response
、kernel.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
构造函数参数没有关系。