在这里我尝试用最简单易懂的语言为你介绍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,都会导致报错。
默认情况是这样的。
默认情况下这个文件是/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',
],
你会得到类似这样的结果。
如果我没有在web.php中指定errorAction那?
如果你没有指定,则yii2会启动vendor/yiisoft/yii2/views/errorHandler/error.php担任显示工作,你会看到如下的显示效果。
一般来说在生产环境我们都配置自己的errorAction视图来优化用户体验。
YII_DEBUG=true当然在我们开发阶段,上面的错误输出是不够的,我们需要知道是哪个文件哪行报了什么具体的错误,因此在YII_DEBUG=true就算你设置了errorAction,当程序出现内部错误的时候,依然会出现详细的信息,如下图这样。
你看到的显示结果是由vendor/yiisoft/yii2/views/errorHandler/exception.php负责。
一个没必要的配置我们在生产环境配置errorAction可以增加用户体验,但是你可恶的老板需要你在开发阶段也有自己公司风格的显示,那你如何做那?
虽然这个需求用处不大但是我们依然可以配置它。
//web.php
'errorHandler' => [
'errorAction' => 'site/error',
'errorView' => '',
'exceptionView' => ''
],
指定errorView & exceptionView,还是我们说的那句话,对于组件驱动类的公共属性一般都是可以配置的。另外如果你做了一个yii2的扩展,也许这些配置是有用处的。
一些其他配置errorHandler还有一些其他的配置,它们可以让你做出更符合你的输出。
maxSourceLines & maxTraceSourceLines这两个参数主要用于开发阶段错误信息源码显示行数,为了更好的说明我们先看下面的图
当一个错误信息发生的时候,上图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
这是一个很有意思的配置项,你可能从来没注意过它,先看看真身。
什么意思那?返回异常链中的前一个异常.
这个配置项使用了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' 五种类型,你可以在报错信息的底部看到它,如图
记住这个配置使用了$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还有一些自己的用法,我下篇为你介绍。