Recipe 15.6. Processing a SOAP Header


15.6.1. Problem

You want to be able to read a SOAP header passed in from a SOAP in your SOAP server.

15.6.2. Solution

Bind a function or method with the same name as the SOAP header:

class pc_SOAP_return_time {     public function set_timezone($tz) {         date_default_timezone_set($tz);     }     public function return_time() {         return date('Ymd\THis');     } }

When ext/soap gets a SOAP header named set_timezone, it calls the set_timezone( ) method. Data placed inside the set_timezone element is passed as an argument.

SOAP headers are processed before the SOAP body.

15.6.3. Discussion

Like HTTP , SOAP lets you define both a SOAP header and a SOAP body element. While you must define a SOAP body, SOAP headers are optional. A SOAP header usually contains information such as authentication credentials or other data that's applicable to all requests you make to the service, instead of being specifically related to that particular method you're invoking.

When ext/soap sees a client request with a SOAP header, it will first try to invoke a function with that name. When that function ends, it will then invoke the function specified in the SOAP body. This allows you to take care of any pre-request work based on SOAP header data. For example, if there are authentication credentials in the header, you can validate the user or throw a SOAP fault if he's unauthorized.

Example 15-9 shows a version of the return_time SOAP server from Example 15-7 that lets you modify the time zone by setting a SOAP header instead of passing it as an optional parameter.

Processing a SOAP header

<?php class pc_SOAP_return_time {     public function set_timezone($tz) {         date_default_timezone_set($tz);     }     public function return_time() {         return date('Ymd\THis');     } } $server = new SOAPServer(null, array('uri'=>'urn:pc_SOAP_return_time')); $server->setClass('pc_SOAP_return_time'); $server->handle(); ?>

Example 15-9 supports two methods: set_timezone( ) and return_time( ). In practice, the first method is supposed to be invoked via a SOAP header and the second from the SOAP body, but ext/soap doesn't really distinguish between the two in a programmatic fashion.

However, when ext/soap sees a SOAP header, it will try to call the method with that before processing the body. Therefore, now you can pass a SOAP header named set_timezone to set the time zone to one other than the web server default. The header should contain the name of the time zone as data.

Then, after setting the time zone, the SOAP server will examine the SOAP body. When it finds the usual return_time request, it returns the date. However, the altered time zone value will still persist, so the date is shifted accordingly.

Example 15-10 shows how you call this from PHP.

Getting the time using SOAP and setting the time zone using a SOAP header

<?php $opts = array('location' => 'http://api.example.org/getTime',               'uri' => 'urn:pc_SOAP_return_time'); $client = new SOAPClient(null, $opts); $set_timezone = new SOAPVar('Europe/Oslo', XSD_STRING); $tz = new SOAPHeader('urn:pc_SOAP_return_time', 'set_timezone', $set_timezone); $result = $client->__soapCall('return_time', array(), array(), array($tz)); print "The local time is $result.\n"; ?>

After creating a SOAPClient for the service, you create the SOAPHeader. This SOAPHeader element lives in the urn:pc_SOAP_return_time XML namespace and is named set_timezone. The ext/soap extension doesn't actually use the XML namespace value, (this may differ on other SOAP servers), but the header name is important, as that controls which method the SOAPServer invokes.

The third argument to the SOAPHeader constructor, $set_timezone, is the data contained inside the SOAP header. In Example 15-10, it's a SOAPVar.

The SOAPVar class is a low-level class used for creating SOAP variables, such as strings and arrays. When you are sending data in the SOAP body, you rarely need to use this class. However, due to limitations in ext/soap, it comes in handy when dealing with SOAP headers.

While building parts of the SOAP request using SOAPVar is cumbersome, it does give you complete control over what's sent. This code creates a string with a value of Europe/Oslo. The XSD_STRING constant is one of many XML Schema and SOAP constants registered by the ext/soap extension. See the SOAP page in the PHP manual at http://www.php.net/soap for the complete list.

The request in Example 15-10 serializes as:

<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope     xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"     xmlns:ns1="urn:pc_SOAP_return_time"     xmlns:xsd="http://www.w3.org/2001/XMLSchema"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"     SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">     <SOAP-ENV:Header>         <ns1:set_timezone>Europe/Oslo</ns1:set_timezone>     </SOAP-ENV:Header>     <SOAP-ENV:Body>         <ns1:return_time/>     </SOAP-ENV:Body> </SOAP-ENV:Envelope>

If the SOAP client specifies a header, but you lack a method to process it, ext/soap will skip the method and move directly to the body. However, if the header's mustUnderstand attribute is flagged as TRue, then the SOAPServer will issue a SOAP fault with a fault code of SOAP-ENV:MustUnderstand and a fault string of Header not understood.

15.6.4. See Also

Recipe 15.7 for generating a SOAP header; Recipe 26.1 for using a a SOAP header; documentation on SOAPHeader at the following address: http://www.php.net/manual/function.soap-soapheader-construct.php.




PHP Cookbook, 2nd Edition
PHP Cookbook: Solutions and Examples for PHP Programmers
ISBN: 0596101015
EAN: 2147483647
Year: 2006
Pages: 445

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net