2

我正在使用 trigger_error 在自定义类中“抛出”错误。我的问题是 trigger_error 打印出调用 trigger_error 的行号。例如,给定以下代码:

01    <?php
02        class Test {
03            function doAction() {
04                $this->doSubAction();
05            }
06            
07            function doSubAction() {
08                if(true)
09                    trigger_error('Custom error', E_USER_WARNING);
10            }
11        }
12        
13        $var = new Test();
14        $var->doAction();
15    ?>

PHP 将打印出以下内容:

警告:第9test.php中的自定义错误

您如何让 PHP 返回调用 doAction() 函数的行(在类外部调用的方法,忽略内部进行的所有调用),如下所示?

警告:第14test.php中的自定义错误

编辑:将我的示例修改为更接近我想要实现的目标。

4

5 回答 5

2

最好的办法是设置一个显示完整堆栈跟踪的错误处理程序。

设置一个自定义错误处理程序,并在其中调用 debug_print_backtrace()。您会发现这通常很有用,在这种特定情况下也是如此。

于 2008-10-09T03:08:37.960 回答
1

好的,对于那些对我的最终解决方案感兴趣的人,我在我们的框架中集成了以下代码,它在我们可以测试的所有情况下返回正确的行号。我们在生产中使用它。

ErrorHandler班级

它捕获未捕获的 PHP 异常、PHP 错误和PEAR::Errors. 如果代码具有一些特定于框架的功能,您将需要对其进行一些修改,但它们应该不难追踪。享受!

于 2009-07-17T19:59:16.607 回答
0

两种选择,没有一种特别好吃:

  • 覆盖在参数中提供 test() __LINE__(例如“ test(__LINE__)”,并将参数提供给 trigger_error)。设置错误处理程序以打印自定义错误消息。注意:这非常丑陋。:-)

  • 设置一个错误处理程序,并让它调用并处理 debug_backtrace() 的巨大输出。此功能在调试时很有用......但对于您正在尝试做的事情来说太过分了。请不要将此功能用作系统常规操作的一部分。

简短的回答:太难了,不要尝试。:-|

于 2008-10-09T03:20:44.800 回答
0

我通常也会在那里放一个 trigger_error() 。这可以确保我确切地知道它被调用的位置以及实际错误发生的位置。然后,我在生产时通过电子邮件将所有错误发送给自己。我知道这不是自动的,但至少你可以追踪发生了什么。

于 2008-10-09T04:19:03.840 回答
0

我想我会把我的两分钱投入锅中,并讨论我通常使用的东西,无论是按原样还是进行小的定制,我构建的 PHP 库经常被其他开发人员使用。

我将程序执行过程中可能出现的错误分为两类:错误编程导致的错误和由于用户错误或某些外部因素导致的错误。对于前者,我将 trigger_error 与 E_USER_ERROR 结合使用,后者是一个异常,特别是一个包异常,然后由库中的所有其他异常继承。

开发错误的一个例子是在参数中传递一个整数,该参数应该是一个字符串(V7 之前),或者访问一个不存在的类的方法或属性。(您可以在这里发挥您自己的开发人员想象力。)显然,另一个开发人员不会关心错误是在 __get 或 __set 语句或其他一些魔术构造的深处产生的,而是他们会想知道特别是他们的错误在哪里。让我们面对现实吧……开发人员不喜欢费力地回溯。

所以我用来本地化错误消息的方法很简单:

function localize_error_msg($msg, $level) {
    $level = (int)$level;
    $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, $level + 1)[$level];
    return $msg . " in " . $backtrace['file'] . " on line " . $backtrace['line'];
}

我传入取决于所使用的构造的回溯级别,通常为 1 或 2,其余的都是不言自明的。

为了防止“in file on line n”的重复序列,我添加了这个错误处理程序:

set_error_handler(function($errno, $errstr, $errfile, $errline) {
    if (preg_match('/on line \d+$/', $errstr) === 1)
        die($errstr);
    else return false;
}, E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE);

同样,我喜欢保持简单。有人可能会争辩说,错误消息的本地化应该在处理程序中进行,但是,您必须能够传递深度,现在处理程序内部的深度又增加了 2 层,而且,它在之后变得混乱那。

快乐的足迹!

于 2016-02-10T00:45:39.913 回答