从PHP外部打印PHP运行调用堆栈

时间:2011-12-01 04:20:12

标签: php debugging stack-trace

PHP中是否存在任何运行时堆栈跟踪功能? (对谁也写Java,我的意思是jstack。)

我得到的PHP后台进程很少,他们会在一些未知行上冻结一次。我可以简单地将它们全部杀死然后重新启动,但这并不能阻止它再次发生。

是否有API可以监视堆栈并告诉?比如JDK提供的jstack实用程序?

1 个答案:

答案 0 :(得分:0)

在调试未知错误方面,您有几个选择。

  • 第一种方法很简单,但需要安装PHP扩展。
  • 第二种方法提供了一种更难以实践的方法,但如果您进入PHP解释器的低级内部工作,这绝对是值得的。此外,这将需要使用--enable-debug配置linux和PHP。
  • 第三个,在我个人看来,最简单的方法不需要使用任何外部程序或添加PHP扩展。

  1. Xdebug

    • 这是一个PHP扩展程序,您可以install并可用于任何网站/页面。
    • 网站上的快速功能列表:
      • 出错时自动堆栈跟踪
      • 函数调用记录
      • 显示增强的var_dump()输出和代码覆盖率信息等功能。
    • 如果你发现自己需要经常调试脚本,那么这个可能是最好的选择。更漂亮的错误显示在我的书中也是一个很好的赞美。

  2. 使用gdb运行崩溃并分析回溯的文件。

    • 这是一种中间到高级的方法,需要使用--enable-debug配置PHP,运行Apache的Linux机器,并且强烈希望/能够理解软件在较低级别上运行的方式 - 电平。
    • 使用gdb运行Apache
      gdb /usr/lib/httpd
    • 然后,您有两个选择:
      • 将apache作为服务器运行,并通过浏览器加载文件,正常情况:
        (gdb) run -X
        ...现在,在您的浏览器中 - 访问正常崩溃的页面并切换回gdb(gdb) backtrace
        ...将打印完整的回溯
      • 或者,使用gdb来运行脚本本身:
        (gdb) run /path/to/the/script.php
        (gdb) backtrace
        ...将打印完整的回溯
    • 如需更多gdb信息,请查看quick-reference guide

  3. 创建一个custom error handler,在抛出错误时打印堆栈跟踪。

    • 为了确保捕获所有错误,您可以捕获错误,异常和PHP的关闭事件。
    • 要调试单个页面,就像创建一个处理错误的函数一样简单,然后将该函数粘贴到您遇到问题的页面顶部。更进一步,我有一个“错误处理”类,它位于一个单独的文件中,只需在需要时包含它(简化版本如下)。您可以调整每种方法以满足您的显示需求,甚至可以按错误数量处理错误!
    • 然后,要使用此功能,只需将require('ErrorHandler.php');添加到页面顶部,它就会自动注册以处理任何错误。当然,请务必更新include-path以指向实际文件。
  4. ErrorHandler.php:

    <?php
    class ErrorHandler {
        public static function captureError($err_no, $message, $file, $line) {
            echo '<strong>Error (#' . $err_no . '):</strong> ' . $message . ' in ' . $file . ' on line #' . $line . '<br />';
            debug_print_backtrace();
        }
    
        public static function captureException($exception) {
            echo '<pre>' . print_r($exception, true) . '</pre>';
        }
    
        public static function captureShutdown() {
            if (($error = error_get_last()) !== null) {
                debug_print_backtrace();
            }
        }
    }
    set_error_handler(array('ErrorHandler', 'captureError'));
    set_exception_handler(array('ErrorHandler', 'captureException'));
    register_shutdown_function(array('ErrorHandler', 'captureShutdown'));
    ?>