实验
承接上一篇:mengkang.net/978.html
Symfony 命令行是如何把错误转成异常的呢?
原来是使用了ErrorException
有了这个类就太好了,命令行可能感触不是特别明显,对于 web 来说简直就是福音了。
下面做一个小实验,当什么都没有设置的时候,以下代码和其错误信息如下:
function testError(){
return explode("xxx");
}
testError();
[21-Mar-2018 15:42:25 PRC] PHP Warning: explode() expects at least 2 parameters, 1 given in /xxx/test.php on line 4
看不到具体的参数,也看不到调用栈。这里没有演示,比如很多函数的相互嵌套调用。仅仅这一行,很难知道这个请求的具体流程。(这一行演示不明显,可以自己加几个文件的包含)。
将代码改成
function testError(){
return explode("xxx");
}
try{
testError();
}catch(Exception $e){
var_export($e->getTrace());
}
echo 1;
页面能正常输出1,但是无法打印出异常的调用栈,php 错误日志里面和没有使用try-catch 一样,没有调用栈。
改进
然后我们如果使用set_error_handler + ErrorException之后,就非常清晰了,很便于错误的追踪。
function my_error_handler($severity, $message, $file, $line) {
throw new ErrorException($message, 0, $severity, $file, $line);
}
set_error_handler("my_error_handler");
function testError(){
return explode("xxx");
}
try{
testError();
}catch(Exception $e){
var_export($e->getTrace());
}
最后打印出来的信息就是
array (
0 =>
array (
'function' => 'exception_error_handler',
'args' =>
array (
0 => 2,
1 => 'explode() expects at least 2 parameters, 1 given',
2 => '/Users/zhoumengkang/Downloads/xxx.php',
3 => 19,
4 =>
array (
),
),
),
1 =>
array (
'file' => '/Users/zhoumengkang/Downloads/xxx.php',
'line' => 19,
'function' => 'explode',
'args' =>
array (
0 => 'xxx',
),
),
2 =>
array (
'file' => '/Users/zhoumengkang/Downloads/xxx.php',
'line' => 12,
'function' => 'testError',
'args' =>
array (
),
),
)
这样就能看见着整个调用栈和每个函数的传递的参数。不仅仅是这些信息,因为通过set_error_handler接管了错误处理,所以在出现该错误的其他信息都可以记录了,方便错误的重现和追踪。