13

我正在编写一个允许用户为 SoapClient 指定 URL 的 Web 应用程序。我想验证用户提交表单时 php 是否可以连接到客户端。我想我可以通过 try catch 或 set_error_handler (或两者的某种组合)来做到这一点。但是,对于致命错误,这似乎是不可能的。有没有办法让 SoapClent 测试一个不会引发不可恢复错误的 URL?

Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://example.com/wibble'

我希望它标记错误,因为 URL 不存在,但我希望能够捕获它。

否则,我想我可以尝试自己下载并验证 URL,但我会认为可以从 SoapClient 执行此操作。

这应该是一个致命的错误吗?

编辑

在阅读了 rogeriopvl 的回答后,我重新意识到我应该说我已经尝试了 soapclient 构造函数的“异常”选项和(绝望地)use-soap-error-handler 函数。

4

5 回答 5

23

Are you using xdebug? According to this PHP bug report and discussion, the issue has been fixed at least since PHP 5.1, but this xdebug bug messes with 'fatal error to exception conversions' in a way that the exception is not generated and the fatal error 'leaks through'.

I can reproduce this locally, with xdebug enabled:

try {
  $soapClient = new SoapClient('http://www.example.com');
}
catch(Exception $e) {
  $exceptionMessage = t($e->getMessage());
  print_r($exceptionMessage);
}

This gives me the fatal error you described, without even entering the catch clause:

Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.example.com'

It works if I disable xdebug right before the call:

xdebug_disable();
try {
  $soapClient = new SoapClient('http://www.example.com');
}
catch(Exception $e) {
  $exceptionMessage = t($e->getMessage());
  print_r($exceptionMessage);
}

This triggers the exception as expected, and I get a proper SoapFault Object in the catch clause with a message of:

SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.example.com'

So basically exceptions work as advertised. If they don't work in your case, you might encounter the xdebug bug, or maybe a similar issue with another 3rd party component.

于 2009-09-14T12:57:33.923 回答
1

见:http ://bugs.xdebug.org/view.php?id=249

可能的解决方案:

Index: trunk/www/sites/all/libraries/classes/defaqtoSoapClient.class.php
===================================================================
--- classes/defaqtoSoapClient.class.php
+++ classes/defaqtoSoapClient.class.php
@@ -31,10 +31,23 @@

     try {
+        // xdebug and soap exception handling interfere with each other here 
+        // so disable xdebug if it is on - just for this call
+        if (function_exists('xdebug_disable')) {
+            xdebug_disable();
+        }
       //Create the SoapClient instance
       parent::__construct($wsdl, $options);
     }
     catch(Exception $parent_class_construct_exception) {
+        if (function_exists('xdebug_enable')) {
+            xdebug_enable();
+        }
       // Throw an exception an say that the SOAP client initialisation is failed
       throw $parent_class_construct_exception;
+    } 
+    if (function_exists('xdebug_enable')) {
+        xdebug_enable();
     }
   }
于 2011-07-04T16:06:47.323 回答
1

引用SoapClient 文档

exceptions 选项是一个布尔值,用于定义soap 错误是否引发SoapFault 类型的异常。

因此,您应该尝试以下方法:

$client = new SoapClient("some.wsdl", array('exceptions' => TRUE));

这种方式将引发SoapFault异常,让您可以捕获它们。

于 2009-09-10T17:50:49.160 回答
0

供您参考,我正在使用带有 PHPUnit 的 SoapClient 来测试远程 WebServices 并遇到了同样的问题!

  • 当使用旧的 PHPUnit 版本 (3.3.x) 作为第三方时,phpunit 崩溃
  • 当使用当前版本的 PHPUnit (3.4.6) 作为第三方时,phpunit 显示“RuntimeException”。

这是我的第一个测试方法:

公共函数 testUnavailableURL() {
    $client = new SoapClient("http://wrong.URI");
}

这是 PHPUnit 第一个结果:

有 1 个错误:

1) MyTestCase::testUnavailableURL
运行时异常:


失败!

这是我的第二种测试方法:

公共函数 testUnavailableURL() {
        尝试 {
          $client = @new SoapClient("http://wrong.URI");
        } 捕捉(SoapFault $fault){
          打印“SOAP 故障:(故障代码:{$fault->faultcode},故障字符串:{$fault->faultstring})”;
        }
}

这是 PHPUnit 的第二次测试结果:

Sebastian Bergmann 的 PHPUnit 3.4.6。

.SOAP 故障:(故障代码:WSDL,故障字符串:SOAP-ERROR:解析 WSDL:无法从“http://wrong.URI”加载:无法加载外部实体“http://wrong.URI”
)...

时间:3 秒,内存:4.25Mb

好的

注意:我找到了一个关于这个主题的 phpunit 票:票 417

于 2010-01-29T14:43:33.620 回答
0

您可以尝试执行 curl 或 fsockopen 请求来检查 URL 是否有效。

于 2009-09-14T06:51:20.053 回答