在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,在第2行和第2行的file3.php中调用 定义...
消息是正确的,但是当我尝试使用$exception->getFile()
和$exception->getLine()
(在我的异常处理程序中)获取文件和行时,我得到foo()定义的文件和行,不是它被称为......
但是使用本机PHP函数,我得到调用函数的文件和行(这就是我想要的)。
答案 0 :(得分:2)
它首先归结为最接近的。
当您使用核心或内置函数时,它们的定义包含在PHP的核心中。这意味着与用户定义的函数相比,函数的定义不可用,其定义很容易获得。
如果在debug_backtrace();
函数中运行$exception->getTrace();
或exception_handler
引用了用户定义函数的错误,您将首先看到该函数的定义,并调用功能第二。如果你调用一个内部函数,你只会看到调用行,因为PHP无法告诉你脚本中的代码行或内部函数定义的包含文件,因为它是在核心中定义的。
这是错误处理的操作顺序。如果你想获得调用函数的实际行,你可以查看跟踪并获取第二个数组对行号的引用。
答案 1 :(得分:1)
好问题!
对于本机和用户定义的函数,事情看起来似乎有所不同。但是,一个显而易见的事情是,如果它是原生的,那么它真的可以告诉你函数的定义,因为它是用C编写的,而不是PHP编写的。在用户空间代码的情况下,很高兴找到它被调用的位置。一种方法是从捕获的异常中解析该错误消息,您可以获取创建它的文件和行。
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