即使在捕获异常后,PHP SoapClient在脚本完成时会触发致命错误?

时间:2014-01-16 10:15:43

标签: php logging soap fatal-error

对于已知不包含有效WSDL的URL,请考虑运行以下脚本:

<?php

echo "start\n";

try {
   $test = new SoapClient ('http://www.example.com/');
} catch (Exception $e) {
   echo "Caught exception\n";
}

echo "end\n";

正如预期的那样,它在运行时会注销以下内容:

start 
Caught exception 
end

因此尽管无法连接到SOAP服务器,脚本仍然运行完成。这正是我所期待的。我没想到的是以下内容也被记录到/ var / log / php_error:

  

PHP致命错误:SOAP-ERROR:解析WSDL:找不到&lt; definitions&gt;在第6行的soapfail.php中的“http://www.example.com/”中

如果你打开了display_errors,那么结果看起来很奇怪。

start
PHP Fatal error:  SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.example.com/' : Extra content at the end of the document
 in soapfail.php on line 6
Caught exception
end

在这种情况下,即使脚本没有在此时停止执行,PHP也会发出致命错误。显然,这是一个非常简化和人为的例子,但我在一个实时系统中发现了这种行为,该系统正在针对已经关闭的服务器执行SOAP请求。日志中出现的致命错误导致我们相信我们未能正确处理错误,而事实上似乎PHP只是在它不应该发出致命错误通知时。

除了关闭日志记录(真的不是一个选项)之外,我还能做些什么吗?

更新:我正在使用的PHP版本是完整的:

PHP 5.4.6-1ubuntu1.5(cli)(建于2013年12月12日04:39:44) 版权所有(c)1997-2012 PHP小组 Zend Engine v2.4.0,版权所有(c)1998-2012 Zend Technologies     与Xdebug v2.2.1,版权所有(c)2002-2012,作者Derick Rethans

我也在家用机器上进行了测试,结果相似。

PHP 5.5.5(cli)(建于:2013年10月20日23:15:05) 版权所有(c)1997-2013 PHP小组 Zend Engine v2.5.0,版权所有(c)1998-2013 Zend Technologies     与Xdebug v2.2.2,版权所有(c)2002-2013,作者Derick Rethans

更新2:

我提交了一份错误报告,因为这对我来说似乎不正确。 Report on php.net

3 个答案:

答案 0 :(得分:1)

这是一个错误。我同意你的第二次更新。由于SSL证书名称不匹配,我得到了它。

我能够使用@运算符来抑制输出中的错误,但是在关闭时它仍然会导致最终“哎呀,之前没有报告此错误,所以现在就是这样!”输出。我的猜测是SOAP库在一个对象的析构函数中触发错误,直到脚本关闭为止。

自定义错误处理程序可能(我还没有测试过)选择忽略该消息,如果你真的想要将它保留在日志之外。某些类型的致命错误无法到达自定义错误处理程序,但这一点在我的应用程序中。

答案 1 :(得分:0)

您可以尝试以下代码:

<?php

    echo "start\n";

    try {
       $test = new SoapClient ('http://www.example.com/', array('exceptions'=>true));
    } catch (Exception $e) {
       echo "Caught exception\n";
    }

    echo "end\n";

?>

它将帮助您捕获异常

答案 2 :(得分:0)

我没有得到这种行为,在运行你的例子时只是一个致命的错误。显然,不同的PHP版本和/或配置是相关的。

我的理解是SOAP客户端应该会成功,如果不成功,那么脚本就不应该继续。 PHP决定我们无法处理此错误是相当不寻常的。

我个人不会忽略错误或试图隐藏它,而是接受PHP认为它是致命的。找到一种方法,既可以确定连接是否会失败,或者将应用程序结构化,以便在发生这种情况时优雅地死亡,理想情况是将过程与其他可能取决于其成功的基本过程隔离开来。