Today I was offered a free lesson in how PHP handles Soap, and more specifically WSDL caching.

When you instantiate a PHP Soap Class you pass it a WSDL (Web Services Description Language) and it looks like this:

[php]

$client = new SoapClient('http://example.com/services/thescript.php?wsdl');

[/php]

Depending on how your caching is setup, this will go out to the WSDL provided, pull in the document and store it in a cache. The default cache for PHP is 86400 seconds. If you are familiar with time in seconds you know that that is 24 hours. So by default you only actually read the WSDL once in a 24 hour period. Normally this is not a problem.

What is a WSDL?

For that answer let's turn to the W3 site:

WSDL is an XML format for describing network services as a set of endpoints operating on messages containing either document-oriented or procedure-oriented information.

So in English that means it is a map to the services provided by the provider. Basically you get a copy of the map, and follow the endpoints to the answers you need.

One basic function of this is that it tells you want methods (services) are available on your fresh client.

When WSDLs go bad

So today one of my providers, without warning, updated their WSDL. This wreaked havoc on my system because I had cached the WSDL on my side for 24 hours (remember, the PHP default). The change was a super simple change, a change in URL for a service, that's it!

The problem was that since PHP had already read the file within 24 hours it didn't care that there was a new file, that the URLs had changed, and so it continued to work as it had before.

The real problem wasn't that the URLs changed, that would have been fine if the provider hadn't shut off the previously reported URLs.

Turn off the cache

So you are left with two options when something like this happens. First, you can sit and wait up to 24 hours for the problem to fix itself. This was not an option for us. The second is to clear your cache and try again.

Now PHP (on Linux) stores the cache for the Soap WSDL in /tmp and I wasn't sure which one of the many files was the actual cache for this particular provider so I decided I would have to tell PHP to not cache the WSDL and try again.

Into php.ini I went, located the soap.wsdlcacheenabled flag. I changed it from 0 to 1

[code]

soap.wsdlcacheenabled=0

[/code]

I saved the file and restarted Apache.

The service continued to fail. I was perplexed. I thought maybe I flubbed the save so I opened the php.ini again located my line and it was fine. So I looked around there to see if maybe I missed another important flag. The only thing I could find was soap.wsdlcachettl listed as the "(time to live) Sets the number of second while cached file will be used instead of original one" I promptly changed this to 0 as well

[code]

soap.wsdlcachettl=0

[/code]

Restarted Apache, and finally my script stopped failing.

I have since re-enabled my cache ttl and enabled flags, as reading the WSDL every time is a resource hog that doesn't need to be in place.

The Lesson Learned

The lesson learned by all today is be aware of your caching, and be aware of the changes you make to your live/production systems.