为啥 PHP 错误会打印两次?
Posted
技术标签:
【中文标题】为啥 PHP 错误会打印两次?【英文标题】:Why are PHP errors printed twice?为什么 PHP 错误会打印两次? 【发布时间】:2012-02-18 14:09:14 【问题描述】:总结
令人惊讶的是,我在 Google 或 SO 上一无所获。当我在 php 中抛出异常时,它会在我的控制台中出现两次,并带有错误消息和堆栈跟踪。第一次打印时显示“PHP 致命错误:...”,第二次打印时仅显示“致命错误:...”。我没有测试这是Apache插件版本。
示例
为了安全起见,一些命名空间和路径用“...”缩短:
$ php 代码/com/.../tabular_data.php PHP 致命错误:在 /home/codemonkey/.../tabular_data.php:56 中带有消息“不支持文件类型”的未捕获异常“异常” 堆栈跟踪: #0 /home/codemonkey/.../tabular_data.php(88): com\...\Tabular_Data->loadFromFile('/home/codemonke...', false) #1 /home/codemonkey/.../tabular_data.php(95): com\...\Tabular_Data::fromFile('/home/codemonke...') #2 主要 在第 56 行的 /home/codemonkey/.../tabular_data.php 中抛出 致命错误:/home/codemonkey/.../tabular_data.php:56 中未捕获的异常“异常”和消息“不支持文件类型” 堆栈跟踪: #0 /home/codemonkey/.../tabular_data.php(88): com\...\Tabular_Data->loadFromFile('/home/codemonke...', false) #1 /home/codemonkey/.../tabular_data.php(95): com\...\Tabular_Data::fromFile('/home/codemonke...') #2 主要 在第 56 行的 /home/codemonkey/.../tabular_data.php 中抛出
问题
我认为它与 stderr 和 stdout 都打印错误有关。无论如何,我如何很好地要求 PHP 只打印一次,最好打印到 stderr?
版本输出
PHP 5.3.9 (cli)(构建时间:2012 年 1 月 11 日 17:09:48) 版权所有 (c) 1997-2012 PHP Group Zend Engine v2.3.0,版权所有 (c) 1998-2012 Zend Technologies
代码
http://pastebin.com/iBUGJ2eY 这是为我显示双重异常的确切代码,名称空间和路径编辑为 foos。请注意,在此安装中,我总是在命令行中遇到双重异常。我几乎可以肯定问题出在 PHP 配置上。
【问题讨论】:
是否涉及任何自定义错误处理程序?使用5.3.9-1~dotdeb.3
我似乎无法通过抛出异常来重现这一点。我只收到第二条消息。
您是否定义了任何自定义错误处理程序?您是否正在重定向错误输出或类似的东西?请展示一个最小的、完整的脚本来重现这个问题。
有问题的代码是一个类定义和一个类实例化。异常发生在实例化期间。这段代码还没有什么花哨的东西。以防万一你可以check it out here。这是令人印象深刻的不起眼和简短。出于好奇,我跑了echo ini_get('error_reporting');
,得到了32767。那是怎么回事?这不应该返回像 E_ALL 这样的字符串吗?
E_ALL
只是E_NOTICE
、E_WARNING
等的位掩码。试试print E_ALL
;你会得到一个数字,因为它只是一个常数。
【参考方案1】:
转载了。第一条错误消息是log_errors
设置的结果,并转到STDERR
。
第二个是display_errors
的结果并转到STDOUT
。
这两个设置都可以在运行时更改。因此,为了“很好地询问 PHP”,这就足够了:
ini_set('log_errors', 1);
ini_set('display_errors', 0);
【讨论】:
正是我想要的。谢谢你 这让我想起了文章“PHP:糟糕设计的分形”t.co/ytXaNjV THX,这就是我需要的答案的一半。我添加了一个自己的答案来完成您的信息;) 如果我设置ini_set('log_errors', 1);
和 ini_set('display_errors', 0);
并且我运行我的 PHP 脚本并从 CLI 抛出异常,我看不到任何输出。未捕获的异常消息在标准输出上输出两次。任何想法?谢谢!
您没有看到任何东西,或者它显示了两次?是哪个?【参考方案2】:
就像answer of Linus Kleen 中写的那样,出现双重消息的原因是display_errors
转到标准输出。
我发现从 php 5.2.4 开始,当display_errors
设置为 1 或“on”时,甚至会发生这种情况。
要恢复正常行为,最好的方法是定义应存储已记录错误的文件,例如添加这个:
error_log = 'd:/logs/php_error.log'
到你的 php.ini。
定义 error_log 文件后,您只会收到一条消息到标准输出,这是您测试所需的内容。
对于生产状态,您可以将display_errors
设置为 0。
【讨论】:
以上是关于为啥 PHP 错误会打印两次?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 pyqt 信号错误会冻结 ui,直到调用另一个 python 函数
如果 error_log 指令只是说“error_log”,那么 PHP 错误会记录到哪里?