PHP SoapClient "Unable to parse URL" error

Posted in PHP -

While testing a web service I was creating in PHP using the PHP SoapClient and SoapServer classes I got the error "Unable to parse URL" from a WSDL file generated using Zend Studio. This post looks at the error and how to fix it.

Example Code

Here's my test code:

$client = new SoapClient('http://host/path/file.php?wsdl');
try {
    $result = $client->callSomething();
catch(Exception $e) {
    echo "Exception: " . $e->getMessage();

It was the line which echoes out $e->getMessage() that I was getting the "Unable to parse URL" error message.

SOAP Address Location

Zend Studio is able to generate WSDL files from your soap class. Near the end of the WSDL file that is generated is the following:

<soap:address location=""/>

The location needs to be a full URL to the script that runs the SOAP web service. I assume there must be some way to get Zend Studio to use the correct full URL but will investigate that another time. For the moment, what you need to do to fix the error is to put the location there, e.g.:

<soap:address location="http://host/path/file.php"/>

WSDL File Caching

The only catch now is that PHP caches WSDL files by default (on CentOS at least anyway, probably the same for other distros). Check your php.ini file for the wsdl setting and location of the cache files. It will be near the end, and by default on CentOS 5 looks like this:

; Enables or disables WSDL caching feature.
; Sets the directory name where SOAP extension will put cache files.
; (time to live) Sets the number of second while cached file will be used
; instead of original one.

From the above we can see the WSDL files will be cached in /tmp for a day. You can either delete all the cached WSDL files at /tmp after making the change to the file, or add the "cache_wsdl" option set to zero when constructing the SoapClient and it will request a fresh copy of the wsdl file each time you run your script. This is probably the best option when developing or debugging anyway.

To switch off caching when constructing the SoapClient in PHP do this:

$client = new SoapClient('http://host/path/file.php?wsdl',
  array('cache_wsdl' => 0));

You can also switch it off in the php.ini file but in a normal production situation it's probably better to cache the WSDL file unless you expect it to be changed often.

Related posts: