对于(Zend Framework)异常,我使用如下所示的简单机制:
namespace Application;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\Log\Logger;
class Module
{
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
// ...
$this->initExceptionHandler($e);
}
public function initExceptionHandler($event)
{
$sharedManager = $event->getApplication()->getEventManager()->getSharedManager();
$serviceManager = $event->getApplication()->getServiceManager();
$sharedManager->attach(
'Zend\Mvc\Application',
[MvcEvent::EVENT_DISPATCH_ERROR, MvcEvent::EVENT_RENDER_ERROR],
function ($event) use($serviceManager) {
// error log
// ...
// error page
...
}
);
}
}
现在我想实现本机PHP错误的错误处理。在PHP 7" 中,现在通过抛出Error例外来报告大多数错误" (s。here)。因此,它们很容易被捕获:使用try-catch
块或通过set_exception_handler(...)
。
为了避免不必要的代码重复,我想"转换" PHP错误异常可以通过已实现的机制捕获异常。我们的想法是"包装" MvcEvent
中的错误并将它们转发给(框架)异常错误处理。到目前为止我尝试过的事情:
// ...
class Module
{
public function onBootstrap(MvcEvent $e)
{
// ...
$this->initExceptionHandler($e);
$this->initErrorHandler($e);
}
// ...
public function initErrorHandler($event)
{
set_exception_handler(function (\Throwable $exception) use ($event) {
$event->getApplication()->getEventManager()->trigger(MvcEvent::EVENT_DISPATCH_ERROR, $event);
});
}
}
结果只是一个白页而没有错误消息(所以页面上没有任何内容,自定义错误日志中没有新内容,syslog
中没有新内容。)
如何将PHP本机错误处理停靠/连接到(框架)异常处理,以便错误导致错误事件的触发并可以作为(框架)异常处理?
更新
日志记录的问题是,$event#params['exception']
未设置,因此无法执行$serviceManager->get('ErrorLogger')->crit($event->getParam('exception'), $extra);
中的行Module#initExceptionHandler(...)
。现在我手动设置此$event
的其他参数:
public function initErrorHandler(MvcEvent $event)
{
set_exception_handler(function (\Throwable $exception) use ($event) {
$event->setError(Application::ERROR_EXCEPTION);
$routeMatch = $event->getRouteMatch();
$controllerName = 'Application\Controller\Error';
$event->setController($controllerName);
$controllerManager = $event->getApplication()->getServiceManager()->get('controller_manager'); // ->get('controllers');
$controller = $controllerManager->get($controllerName);
$event->setControllerClass(get_class($controller));
$event->setParam('exception', $exception);
$viewModel = new ViewModel();
$viewModel->setCaptureTo('content');
$viewModel->setTemplate('error/index');
$viewModel->setTerminal(false);
$viewModel->setVariables([
'message' => 'An error occurred during execution; please try again later.',
'display_exceptions' => true
]);
$event->setResult($viewModel);
// From this moment the framework exception handling starts and cares about the logging and displaying the error data.
// $event->getApplication()->getEventManager()->trigger(MvcEvent::EVENT_DISPATCH_ERROR, $event);
$event->setName(MvcEvent::EVENT_DISPATCH_ERROR);
$event->getApplication()->getEventManager()->triggerEvent($event);
return false;
});
}
这样我就可以正常运行了。但是在前端,我仍然得到一个空白的页面。 这里有什么问题以及如何立即显示错误页面?
更新
我认为,这是一个可怕的逻辑错误 - 我试图在 set_exception_handler(...)
调用之后处理一些框架内容。我看得对吗?如果是这样,它就不能以这种方式工作。 如何解决这个难题/什么是解决方法?