15.2.1. ProblemYou want to create a SOAP server to respond to SOAP requests. 15.2.2. SolutionUse 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. DiscussionThere are three steps to creating a SOAP server with ext/soap's SOAPServer class:
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
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
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
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 Also14.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. |