如何重新定义 Slim v3 的错误处理程序?

How do I redefine Slim v3's error handler?

我按照 Slim v3 文档了解了如何重新定义框架的内置错误处理程序,以防止使用以下代码将错误输出到响应:

$settings = require __DIR__ . '/../src/settings.php';
$app = new \Slim\App($settings);

// Errors to log rather than to end user
$c = $app->getContainer();

$c['errorHandler'] = function ($c) {
    return function ($request, $response, $exception) use ($c) {
        $c['logger']->error("Error 500 diverted: ".$exception->getMessage());
        return $c['response']->withStatus(500)
                             ->withHeader('Content-Type', 'text/html')
                             ->write('Something went wrong on our side!');
    };
};

然而我的 API 仍然吐出 Slim 的默认处理程序,其中包含完整的堆栈跟踪和告密的 Slim Application Error 字符串...尽管有用,但我更愿意将这些信息发送给 Slim 的日志(独白)和面向客户的一些不那么显露的东西。是否有任何理由可以有效地忽略此服务重新定义?

此代码有效:

<?php
$app = new \Slim\App();
$container = $app->getContainer();

$container['errorHandler'] = function ($c) {
    return function ($request, $response, $exception) use ($c) {
        // log error here
        return $c['response']->withStatus(500)
                             ->withHeader('Content-Type', 'text/html')
                             ->write('Something went wrong on our side!');
    };
};
$container['phpErrorHandler'] = function ($c) {
    return function ($request, $response, $error) use ($c) {
        // log error here
        return $c['response']->withStatus(500)
                             ->withHeader('Content-Type', 'text/html')
                             ->write('Something went wrong on our side (again)!');
    };
};

$app->get('/exception', function ($req, $res, $args) {
    // errorHandler will trap this Exception
    throw new Exception("An error happened here");
});

$app->get('/php7', function ($req, $res, $args) {
    $x = function (int $x) {
        return $x;
    };

    // phpErrorHandler wil trap this Error
    $x('test');
});

$app->get('/warning', function ($req, $res, $args) {
    $x = UNDEFINED_CONSTANT;
});

$app->run();

如您所见,您需要注册一个 errorHandler 来捕获异常,并注册一个 phpErrorHandler 来捕获 PHP 7 Errors.

请注意,两者都不会捕获 PHP 通知,如 /warning 路线所示。要捕获它,您需要注册自己的错误处理程序:

set_error_handler(function ($severity, $message, $file, $line) {
    if (!(error_reporting() & $severity)) {
        // This error code is not included in error_reporting, so ignore it
        return;
    }
    throw new \ErrorException($message, 0, $severity, $file, $line);
});