Recipe 15.2. Serving a SOAP Method


15.2.1. Problem

You want to create a SOAP server to respond to SOAP requests.

15.2.2. Solution

Use ext/soap's SOAPServer class. Here's a server that returns the current date and time:

<?php class pc_SOAP_return_time {     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(); ?>

15.2.3. Discussion

There are three steps to creating a SOAP server with ext/soap's SOAPServer class:

  1. Create a class to process SOAP methods.

  2. Create an instance of a SOAP server and associate the processing class with the instance.

  3. Instruct the SOAP server to process the request and reply to the SOAP client.

The ext/soap SOAPServer class can use functions or classes to handle SOAP requests. Example 15-4 shows the pc_SOAP_return_time class, which has one method, return_time( ).

pc_SOAP_return_time class

<?php class pc_SOAP_return_time {     public function return_time() {         return date('Ymd\THis');     } } ?>

Once the class is defined, instantiate a SOAPServer object. If you have a WSDL file for your service, pass it as your first argument; otherwise, as in this case, pass null. The second argument contains your configuration options. Here, there's only uri, which specifies the SOAP server namespace. In Example 15-5, it's urn:pc_SOAP_return_time.

Instantiating SOAPServer

<?php $server = new SOAPServer(null, array('uri'=>'urn:pc_SOAP_return_time')); ?>

When ext/soap processes a SOAP request, it doesn't pay attention to the name of your PHP class, such as pc_SOAP_return_time. What really matters is the XML namespace, which you've just set as urn:pc_SOAP_return_time.

Next, call SOAPServer::setClass( ) with a class name. When a SOAP server receives a request for a method, it will try to call a class method with the same name:

<?php $server->setClass('pc_SOAP_return_time'); $server->handle(); ?>

Last, tell the server to respond to the request by calling SOAPServer::handle( ). The SOAPServer automatically processes the $GLOBALS['HTTP_RAW_POST_DATA'] variable, which is where PHP stores POST data.

If your SOAP request comes from another source, say an email message, you can pass that data to SOAPServer::handle( ):

<?php $server->handle($soap_message_from_someplace_else); ?>

In both cases, the SOAPServer takes care of parsing the SOAP data and routing everything accordingly.

To call this procedure using an ext/soap client, use the code in Example 15-6.

Getting the time using SOAP

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

This prints:

The local time is 20060816T083225.

Instead of binding an entire class, you can also associate an individual function:

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

You can call SOAPServer::addFunction( ) with an array of function names to bind more than one function:

<?php $server = new SOAPServer(null, array('uri'=>'urn:pc_SOAP_return_time')); // array of functions to expose $functions = array('return_time', 'return_date'); $server->addfunction($functions); ?>

Another option is to bind all functions:

<?php $server = new SOAPServer(null, array('uri'=>'urn:pc_SOAP_return_time')); // add *all* functions $server->addfunction(SOAP_FUNCTIONS_ALL); ?>

This is strongly discouraged, as it's a giant security risk. You may accidentally include a function with secret information, which is then exposed since you're using SOAP_FUNCTIONS_ALL. You should always explicitly enumerate the functions you wish to expose on an opt-in basis.

If the method isn't labeled as public or isn't defined at all, such as set_time, the server replies with a SOAP fault, with a faultstring of Function 'set_time' doesn't exist and a faultcode of SOAP-ENV:Server.

To change this behavior, bind a class with a __call( ) method:

<?php class pc_SOAP_Process_All_Methods {     // Handle any undefined methods here     public function __call($name, $args) {         // ...     } } $server = new SOAPServer(null, array('uri'=>'urn:pc_SOAP_Process_All_Methods')); $server->setClass('pc_SOAP_Process_All_Methods'); $server->handle(); ?>

If you build PHP with the zlib extension, SOAPServer will automatically support gzipped and compressed requests. It will uncompress the data before processing it.

15.2.4. See Also

14.2 for calling a SOAP method; 15.3 for accepting arguments in a SOAP method; Recipe 15.5 for throwing SOAP faults; documentation on ext/soap at http://www.php.net/soap.




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

Similar book on Amazon

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