简体   繁体   中英

Checking a URL is valid (from php soap client)

I am writing a web app which will allow the user to specify a URL for a SoapClient. I wanted to validate that php can connect to the client when the user submits a form. I thouhgt I could do this via try catch or set_error_handler (or some combination of the two). However it looks like this is not possible for fatal errors. Is there a way to get SoapClent to test a URL which won't throw an unrecoverable error?

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

I want it to flag an error as the URL doesn't exist, but I would like to be able to catch it.

Otherwise I suppose I could try to download and validate the URL myself, but I would have thought that it would be possible to do it from the SoapClient.

Should this be a fatal error?

Edit

After reading rogeriopvl's answer I reaslise that I should have said that I had tried the 'exceptions' option to the soapclient constructor and (in desperation) the use-soap-error-handler function.

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.

Quoting SoapClient documentation :

The exceptions option is a boolean value defining whether soap errors throw exceptions of type SoapFault.

So you should try something like:

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

This way will throw SoapFault exceptions allowing you to catch them.

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

Possible solution:

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

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

For your information, i'm using SoapClient with PHPUnit to test remote WebServices and got the same problem!

  • when using an old PHPUnit version (3.3.x) as third party, phpunit crash
  • when using current version of PHPUnit (3.4.6) as third party, phpunit display "RuntimeException".

Here is my first test method :

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

Here is PHPUnit first result :

There was 1 error:

1) MyTestCase::testUnavailableURL
RuntimeException: 


FAILURES!

Here is my second test method :

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

Here is PHPUnit second test result :

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

NB: i found a phpunit ticket on this subject : ticket 417

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM