在file1.php:中
set_error_handler('my_error_handler');
set_exception_handler('my_exception_handler');
function my_error_handler($errNo, $errStr, $errFile, $errLine, $whatever = null){
// here ErrFile and $errLine are correct only for native funcs...
throw New ErrorException($errStr, 0, $errNo, $errFile, $errLine);
}
function my_exception_handler($exception){
print $exception->getLine(); // correct only for native functions
print $exception->getFile(); // correct only for native functions
}
在file2.php中,有一个示例函数定义:
function foo($requiredArg){
}
在file3.php中,调用foo:
foo();
生产:
foo()缺少参数1,在file3.php的第2行调用定义
消息是正确的,但当我尝试获取带有$exception->getFile()
和$exception->getLine()
的文件和行(在我的异常处理程序中)时,我会获取定义foo()的文件和行将,而不是调用它的位置。。。
但是使用本机PHP函数,我可以获得调用该函数的文件和行(这正是我想要的)。
它简单地归结为最接近的第一个。
当您使用核心或内置函数时,它们的定义包含在PHP的核心中。这意味着,与用户定义函数相比,函数的定义是不可用的,因为用户定义函数的定义很容易获得。
如果在引用用户定义函数错误的exception_handler
函数中运行debug_backtrace();
或$exception->getTrace();
,您将首先看到函数的定义,然后看到函数的调用。如果你调用一个内部函数,你只会看到调用行,因为PHP无法告诉你脚本或包含文件中定义了内部函数的代码行,因为它是在核心中定义的。
这是错误处理的操作顺序。如果您想获得调用该函数的实际行,可以查看跟踪并获取第二个数组对行号的引用。
好问题!
对于本机函数和用户定义函数,情况似乎有所不同。不过,有一点很明显,如果函数是本机函数,就不能真正告诉你它是在哪里定义的,因为它是用C编写的,而不是用PHP编写的。如果是用户空间代码的话,如果能找到它是在哪里调用的,那就太好了。一种方法是从捕获的Exception中解析错误消息,您可以获得创建它的文件和行。
function my_exception_handler($exception)
{
$message = $exception->getMessage();
$file = $exception->getFile();
$line = $exception->getLine();
if(strpos($message, 'called in') !== false) {
preg_match('/called in .*php/', $message, $matches);
$file = str_replace('called in ', '', $matches[0]);
preg_match('/on line 'd/', $message, $matches);
$line = str_replace('on line ', '', $matches[0]);
}
echo 'line: ' . $line . PHP_EOL;
echo 'file: ' . $file . PHP_EOL;
}
修改my_exception_handler
:的基于输出的问题描述
line: 4
file: /tmp/file3.php