Yii2:仅对致命错误使用错误处理程序或指定处理的错误类型

时间:2016-02-20 11:37:04

标签: php error-handling yii2

Yii2拥有自己的error handler,可以将所有非致命的php错误转换为可捕获的异常。

是否可以仅将其用于处理致命错误或(更好地)明确指定,哪些错误应由yii错误处理程序处理,哪些应由内部php处理程序处理?

即。在开发环境中,我希望所有错误都抛出异常并提供带有跟踪的错误页面。

但是在prod环境中我只想要使用yii呈现错误页面的致命错误,但是通知和警告应该只是去标准的php日志而不会抛出一个exeption。

目前,如果我将YII_ENABLE_ERROR_HANDLER设置为true,我会在通知上获得例外(我不希望它在prod上);如果我将它设置为false,我会丢失致命的错误页面;并且我将其设置为true并将error_reporting设置为0,我将错误记录错误。

1 个答案:

答案 0 :(得分:0)

编辑:我创建了一个实现下述行为的package

无法以这种方式配置Yii2的错误处理程序。但是可以创建自己的错误处理程序,扩展yii\web\ErrorHandler(或yii\console\ErrorHandler,如果需要)。

namespace app\web;

use yii\web\ErrorHandler as BaseErrorHandler;

class ErrorHandler extends BaseErrorHandler {


    /**
     * @var array Used to specify which errors this handler should process.
     *
     * Default is ['fatal' => true, 'catchable' => E_ALL | E_STRICT ]
     *
     * E_ALL | E_STRICT is a default from set_error_handler() documentation.
     *
     * Set
     *     'catchable' => false
     * to disable catchable error handling with this ErrorHandler.
     *
     * You can also explicitly specify, which error types to process, i. e.:
     *     'catchable' => E_ALL & ~E_NOTICE & ~E_STRICT
     */
    public $error_types;

    /**
     * @var boolean Used to specify display_errors php ini setting
     */
    public $display_errors = false;

    /**
     * @var string Used to reserve memory for fatal error handler.
     */
    private $_memoryReserve;
    /**
     * @var \Exception from HHVM error that stores backtrace
     */
    private $_hhvmException;

    /**
     * Register this error handler
     */
    public function register()
    {
        // by default process all errors
        // E_ALL | E_STRICT is a default from set_error_handler() documentation
        $default_error_types = [ 'fatal' => true, 'catchable' => E_ALL | E_STRICT ];
        // merge with application configuration
        $error_types = array_merge($default_error_types, (array) $this->error_types);

        ini_set('display_errors', $this->display_errors);
        set_exception_handler([$this, 'handleException']);
        if (defined('HHVM_VERSION')) {
            set_error_handler([$this, 'handleHhvmError'], $error_types['catchable']);
        } else {
            set_error_handler([$this, 'handleError'], $error_types['catchable']);
        }
        if ($this->memoryReserveSize > 0) {
            $this->_memoryReserve = str_repeat('x', $this->memoryReserveSize);
        }
        if ($error_types['fatal']) {
            register_shutdown_function([$this, 'handleFatalError']);
        }
    }

}

然后可以配置错误处理程序:

'components' => [
    'errorHandler' => [
        'class' => 'app\web\ErrorHandler',
        'error_types' => [
            'fatal' => true,
            'catchable' => YII_DEBUG ? (E_ALL | E_STRICT) : false
        ],
        'display_errors' => ini_get('display_errors')
    ],
],

在这个示例配置中,我们说错误处理程序应始终处理致命错误,但只有在我们处于调试模式时才处理可捕获错误。在生产模式下,所有可捕获错误都将由内部php错误处理程序处理,并且如果您配置它将出现在错误日志中。

据说

display_errorsphp.ini.htaccess继承服务器php配置。