代码之家  ›  专栏  ›  技术社区  ›  Andrew Moore

在php中使用trigger_错误时如何获得正确的行号?

  •  1
  • Andrew Moore  · 技术社区  · 16 年前

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

    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将打印出以下内容:

    警告: 自定义错误 测试程序 在线

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

    警告: 自定义错误 测试程序 在线 十四

    编辑: 修改了我的示例,使其更接近我正在尝试实现的目标。

    5 回复  |  直到 9 年前
        1
  •  2
  •   Jerub    16 年前

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

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

        2
  •  0
  •   Rob Howard    16 年前

    有两种选择,两种都不是特别好吃的:

    • override具有test()提供 __LINE__ 在辩论中(如 test(__LINE__) “,并给出触发\u错误的参数。”设置错误处理程序以打印自定义错误消息。 注: 这真是太难看了。-)

    • 设置一个错误处理程序,让它调用并处理debug backtrace()的大量输出。此函数在调试…但对你想做的事太过分了。请不要将此功能用作系统正常运行的一部分。

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

        3
  •  0
  •   Darryl Hein IrishChieftain    16 年前

    我通常也会在那里设置一个触发器。这样可以确保我确切地知道调用它的位置以及实际错误发生的位置。然后,我在制作过程中会通过电子邮件将所有错误发送给自己。我知道这不是自动的,但至少你能追踪到发生了什么。

        4
  •  0
  •   Andrew Moore    15 年前

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

    ErrorHandler class

    它捕获未捕获的PHP异常、PHP错误和 PEAR::Error 你需要稍微修改一下,代码有一些框架特定的功能,但它们不应该很难被跟踪。享受!

        5
  •  0
  •   Borgboy    9 年前

    我想我会把我的两分钱投入到这个花盆中,讨论一下我通常使用什么,无论是按原样使用还是使用小的定制,用于我构建的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,其余的都是不言而喻的。

    为了防止“i n 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);
    

    同样,我喜欢保持简单。可以说,错误消息的本地化应该发生在处理程序中,但是之后,您必须能够传递深度,这在处理程序中又增加了两个层次,并且,在这之后会变得混乱。

    快乐小径!