2009-09-10 75 views
13

我在写一个web应用程序,它将允许用户指定一个SoapClient的URL。我想验证当用户提交表单时,php可以连接到客户端。我想你可以通过try catch或者set_error_handler(或者两者的组合)来做到这一点。但是看起来这是致命错误不可能的。有没有办法让SoapClent测试一个不会引发不可恢复的错误的URL?检查一个URL是有效的(来自php肥皂客户端)

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

我想标记一个错误,因为URL不存在,但我希望能够抓住它。

否则,我想我可以尝试自己下载并验证URL,但我一直认为它可以从SoapClient中完成。

这是致命的错误吗?

编辑

阅读rogeriopvl的回答后,我reaslise,我应该说,我曾经尝试过“例外”选项给SoapClient的构造函数和(在绝望中)使用皂错误处理函数。

回答

22

您使用的是xdebug吗?根据this PHP bug report and discussion,这个问题至少在PHP5.1之后得到了修正,但this xdebug bug以'异常转换致命错误'的方式混淆,这种异常不会产生,并且致命错误'泄漏通过'。

我可以在本地复制本,并启用了XDebug:

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

这给了我你所描述的致命错误,甚至没有进入catch子句:

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

它的工作原理,如果我禁用xdebug就在通话之前:

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

这会触发预期的异常,而我得到的catch子句在适当的SOAPFault对象与消息:

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

所以基本上异常工作作为标榜。如果它们不适用于您的案例,那么您可能会遇到xdebug错误,或者可能与另一个第三方组件存在类似的问题。

+0

xdebug有bug。这对我来说是新的,谢谢。 – 2009-09-14 15:47:51

+4

这对我来说也是新的 - 没有太多的东西比狩猎调试器本身引起的bug更烦人:/ – 2009-09-14 16:27:16

+1

这是一个Xdebug错误,但我最近修复了这个错误。尽管如此,它并不是发布的一部分。 – Derick 2012-01-17 16:20:23

1

报价SoapClient documentation

例外选项定义肥皂错误是否抛出类型的SOAPFault的异常的布尔值。

所以,你应该尝试类似:

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

这样会抛出异常SoapFault,让您赶上他们。

+0

我试过了,没有工作,应该把它的问题,我的坏,我会更新。 – 2009-09-10 20:50:20

0

你可以尝试做一个curl或fsockopen请求来检查URL是否有效。

+0

这将检查可以从URL获取的内容,但不会检查它是否是真正的WSDL文件。 – 2009-09-14 10:02:21

0

为了您的信息,我使用SoapClient和PHPUnit来测试远程Web服务,并得到了同样的问题!

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

这是我的第一测试方法:

 
public function testUnavailableURL() { 
    $client = new SoapClient("http://wrong.URI"); 
} 

在这里被PHPUnit的第一结果:

 
There was 1 error: 

1) MyTestCase::testUnavailableURL 
RuntimeException: 


FAILURES! 

这是我的第二测试方法:

 
public function testUnavailableURL() { 
     try { 
      $client = @new SoapClient("http://wrong.URI"); 
     } catch (SoapFault $fault) { 
      print "SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})"; 
     } 
} 

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

 
PHPUnit 3.4.6 by Sebastian Bergmann. 

.SOAP Fault: (faultcode: WSDL, faultstring: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://wrong.URI' : failed to load external entity "http://wrong.URI" 
)... 

Time: 3 seconds, Memory: 4.25Mb 

OK 

注:我发现有关此话题的PHPUnit的票:ticket 417

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(); 
    } 
    } 
+0

更好的修复程序已经是Xdebug github存储库的一部分。 – Derick 2012-01-17 16:21:04