2
在这里我尝试用最简单易懂的语言为你介绍yii2中关于错误处理的那些事情。

在yii2中错误处理是以组件的形式存在,通过调用 Yii::$app->errorHandler 可以获得这个对象,我们先来看一下这个对象的内容。

$handler = Yii::$app->errorHandler;
VarDumper::dump($handler,10,true);

输出结果

yii\web\ErrorHandler#1
(
    [maxSourceLines] => 19
    [maxTraceSourceLines] => 13
    [errorAction] => 'site/error'
    [errorView] => '@app/views/site/err.php'
    [exceptionView] => '@app/views/site/err.php'
    [callStackItemView] => '@yii/views/errorHandler/callStackItem.php'
    [previousExceptionView] => '@yii/views/errorHandler/previousException.php'
    [displayVars] => [
        0 => '_GET'
        1 => '_POST'
        2 => '_FILES'
        3 => '_COOKIE'
        4 => '_SESSION'
    ]
    [discardExistingOutput] => true
    [memoryReserveSize] => 262144
    [exception] => null
    [yii\base\ErrorHandler:_memoryReserve] => 'xxxxx'
    [yii\base\ErrorHandler:_hhvmException] => null
    [yii\base\Component:_events] => []
    [yii\base\Component:_behaviors] => null
)

在这里我们看到有诸如 errorAction / errorView / exceptionView 等属性,正是这些属性控制着yii2中各类错误输出,当然作为组件我们也可以在components对其配置,就像下面一样。

'errorHandler' => [
    'errorAction' => 'site/error',
],

事实上在yii2中所有组件的公共属性我们都可以像上面一样去配置。

接下来通过不同的场景来说明如何使用errorHandler

action写错了

这种情况我们经常遇到,比如用户输入了一个错误的url,都会导致报错。

默认情况是这样的。

alt

默认情况下这个文件是/views/site/error.php,通过web.php的如下代码来配置

'errorHandler' => [
    'errorAction' => 'site/error',
],

可以通过修改errorAction更改,在你配置的视图里可以使用$name和$message,分别代表报错的名字和信息。

值得注意的是这个报错信息仅仅在YII_DEBUG=true的情况下才会出现,如果YII_DEBUG=false,则显示默认的An internal server error occurred。

程序内部报错了

比如我们的action内查询了一个数据表,但是该数据表并不存在,这个时候的报错yii2是如何处理的那?问题比较复杂,我们从两个方面说明。

YII_DEBUG=false

当你不处在YII_DEBUG模式下并且在web.php指定了errorAction的情况下,错误的显示还是由errorAction值来接管。

比如如下配置

//index.php
defined('YII_DEBUG') or define('YII_DEBUG', false);
// web.php
'errorHandler' => [
    'errorAction' => 'site/error',
],

你会得到类似这样的结果。

alt

如果我没有在web.php中指定errorAction那?

如果你没有指定,则yii2会启动vendor/yiisoft/yii2/views/errorHandler/error.php担任显示工作,你会看到如下的显示效果。

alt

一般来说在生产环境我们都配置自己的errorAction视图来优化用户体验。

YII_DEBUG=true

当然在我们开发阶段,上面的错误输出是不够的,我们需要知道是哪个文件哪行报了什么具体的错误,因此在YII_DEBUG=true就算你设置了errorAction,当程序出现内部错误的时候,依然会出现详细的信息,如下图这样。

alt

你看到的显示结果是由vendor/yiisoft/yii2/views/errorHandler/exception.php负责。

一个没必要的配置

我们在生产环境配置errorAction可以增加用户体验,但是你可恶的老板需要你在开发阶段也有自己公司风格的显示,那你如何做那?

虽然这个需求用处不大但是我们依然可以配置它。

//web.php
'errorHandler' => [
    'errorAction' => 'site/error',
    'errorView' => '',
    'exceptionView' => ''
],

指定errorView & exceptionView,还是我们说的那句话,对于组件驱动类的公共属性一般都是可以配置的。另外如果你做了一个yii2的扩展,也许这些配置是有用处的。

一些其他配置

errorHandler还有一些其他的配置,它们可以让你做出更符合你的输出。

maxSourceLines & maxTraceSourceLines

这两个参数主要用于开发阶段错误信息源码显示行数,为了更好的说明我们先看下面的图

alt

当一个错误信息发生的时候,上图1处代表最终这个错误的爆发点 而下面的每行表示它的运行路径。

maxSourceLines代表1处相关源码显示行数

maxTraceSourceLines 代表类似2这种相关文件关联处的源码显示行数

默认情况下maxSourceLines=19,maxTraceSourceLines=13。

配置方法

// web.php
'errorHandler' => [
    'errorAction' => 'site/error',
    'maxSourceLines'=>2,
    'maxTraceSourceLines' => 2
],

callStackItemView

在上图我们看到了一个错误发生时经过了很多文件和函数,可能你想知道这每一行是如何显示出来的,callStackItemView就是每一行的视图,默认为vendor/yiisoft/yii2/views/errorHandler/callStackItem.php,你也可以配置它。

// web.php
'errorHandler' => [
    'errorAction' => 'site/error',
    'callStackItemView'=>'xxx'
],

previousExceptionView

这是一个很有意思的配置项,你可能从来没注意过它,先看看真身。

alt

什么意思那?返回异常链中的前一个异常.

这个配置项使用了php原生的Exception::getPrevious,比如我们上图的前一个异常是PDO的报错。

详情可以去 previousExceptionView默认配置项 vendor/yiisoft/yii2/views/errorHandler/previousException.php 中去看已看,当然它也是可以配置的,虽然没什么必要。

// web.php
'errorHandler' => [
    'errorAction' => 'site/error',
    'previousExceptionView'=>'xxx'
],

displayVars

默认显示 '_GET', '_POST', '_FILES', '_COOKIE', '_SESSION' 五种类型,你可以在报错信息的底部看到它,如图

alt

记住这个配置使用了$GLOBALS。

我们可以通过配置减少一些显示,比如只显示$_GET

// web.php
'errorHandler' => [
    'errorAction' => 'site/error',
    'displayVars'=>['_GET']
],

memoryReserveSize

预留内存,防止内存异常的时候错误处理器不能处理错误,默认是262144(256KB),用x作为占位符。如果设置为0则为不预留。

// web.php
'errorHandler' => [
    'errorAction' => 'site/error',
    'memoryReserveSize'=>262144
],

discardExistingOutput

默认为真,处理异常时中断所有输出。当然你可以关闭它。

// web.php
'errorHandler' => [
    'errorAction' => 'site/error',
    'discardExistingOutput'=>262144
],

小结

以上就是关于errorHandler所有配置项,当然errorHandler还有一些自己的用法,我下篇为你介绍。


阿北
4.1k 声望913 粉丝

引用和评论

0 条评论