如何在ZF2中使用框架异常处理来处理PHP 7错误异常?

时间:2016-05-13 16:57:14

标签: php events error-handling event-handling zend-framework2

对于(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(...)调用之后处理一些框架内容。我看得对吗?如果是这样,它就不能以这种方式工作。 如何解决这个难题/什么是解决方法?

0 个答案:

没有答案