I l @ ve RuBoard |
An Alternative PHP/SOAP Implementation: SOAPx4SOAPx4 is a PHP implementation of the Simple Object Access Protocol (SOAP) and Web Services Description Language (WSDL). Developed by Dietrich Ayala, these two standards are implemented as a pair of PHP classes (one for the server, and one for the client), and are freely available under the GNU LGPL at http://dietrich.ganx4.com/soapx4/. SOAPx4 uses an approach similar to that demonstrated in Edd Dumbill's XML-RPC implementation (discussed in the preceding section). Here too, the fundamental unit is a soapval object, which represents a single SOAP value. Multiple soapval objects can be built into a SOAP message, complete with header and body sections. This soapmsg object, once serialized, is suitable for transmission to any SOAP-compliant server or client.
Consider Listing 8.15, which demonstrates the construction of a SOAP request using these objects. Listing 8.15 Constructing a SOAP Request<?php // include class definitions include("class.soap_client.php"); /* create an instance of the soapval object the soapval object constructor requires three parameters soapval(name, type, value) */ $val = new soapval("author", "string", "Oscar Wilde"); /* the serializeval() method serializes the value into XML */ // uncomment the line below to see the serialized value // print $val->serializeval(); /* create an instance of the soapmsg object the soapmsg object constructor requires two parameters: soapmsg(procedure, array of soapval objects) */ $msg = new soapmsg("getRandomQuote", array($val)); /* the serialize() method creates a complete SOAP packet */ print $msg->serialize(); ?> Listing 8.16 demonstrates the SOAP packet resulting from Listing 8.15. Listing 8.16 A SOAP Request<xml version="1.0"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"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/" xmlns: si="http://soapinterop.org/xsd" xmlns:ns6="http://testuri.org" SOAP-ENV: encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <ns6:getRandomQuote> <author xsi:type="xsd:string">Oscar Wilde</author> </ns6:getRandomQuote> </SOAP-ENV:Body> </SOAP-ENV:Envelope> In a similar manner, it's also possible to construct a SOAP response. Listing 8.17 demonstrates how. Listing 8.17 Constructing a SOAP Response<?php // include class definitions include("class.soap_client.php"); // create an instance of the soapval object $val = new soapval("quote", "string", "One man's poetry is another man's poison"); // create an instance of the soapmsg object // note that, in this implementation, the same object is used // to create both requests and responses $msg = new soapmsg("getRandomQuoteResponse", array($val)); // the serialize() method creates a SOAP packet print $msg->serialize(); ?> And Listing 8.18 demonstrates the generated SOAP response. Listing 8.18 A SOAP Response<?xml version="1.0"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"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/"xmlns: si="http://soapinterop.org/xsd" xmlns:ns6="http://testuri.org" SOAP-ENV: encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <ns6:getRandomQuoteResponse> <quote xsi:type="xsd:string">One man's poetry is another man's poison</ quote> </ns6:getRandomQuoteResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope> SOAPx4 also includes two high-level classes, one to instantiate a server and the other to instantiate a client. These high-level classes substantially simplify the work involved in creating and manipulating SOAP requests and responses. In order to better demonstrate how these work, I'll use SOAPx4 to reprise the RPC-based mail service from Chapter 6, "PHP and XML-Based Remote Procedure Calls (RPC)," (Listing 6.29 and Listing 6.30). Listing 8.19 demonstrates the code for the SOAP server. Listing 8.19 A SOAP Server<?php // include class definitions include("class.soap_client.php"); include("class.soap_server.php"); // instantiate a server object $server = new soap_server; // uncomment next line to see server debug messages // $server->debug_flag = true; /* the add_to_map() method adds a procedure to the server's list of exposed public methods the second and third argument specify the data type of the input (arguments) to, and output (return values) from, the procedure respectively. */ $server->add_to_map("getTotalPOP3Messages", array("SOAPStruct"), array("int")); /* the service() function services the SOAP request and sends a SOAP response back to the client */ $server->service($HTTP_RAW_POST_DATA); // function to return number of messages function getTotalPOP3Messages($struct) { // make sure the server supports POP3 // if you're using PHP, you may need to recompile your build // to enable this support $inbox = imap_open ("{". $struct["pop_host"] . "/pop3:110}",$struct["pop_user"], $struct["pop_pass"]); // if connection successfully opened if ($inbox) { // get number of messages $total = imap_num_msg($inbox); imap_close($inbox); return $total; } else { // else generate a SOAP fault $params = array("faultcode" => "75", "faultstring" => "No connection available", "detail" => "Could not connect to POP3 server"); $faultmsg = new soapmsg("Fault", $params, "http://schemas.xmlsoap.org/soap/ envelope/"); return $faultmsg; } } ?> There are two important methods to be aware of when using a SOAP server created with the SOAPx4 class. After an instance of the server class has been created, the add_to_map() method is used to register procedures with the server, together with information on the expected data types of input arguments and return values. Then, the service() method is used to service the incoming SOAP request and return a SOAP packet containing the response. The SOAP client at the other end of the connection needs to generate a SOAP request and decode the response packet containing the results of the procedure call. In SOAPx4, this can be accomplished with just a few lines of code, as Listing 8.20 demonstrates. Listing 8.20 A SOAP Client<html> <head> <basefont face="Arial"> </head> <body> <?php if(!$_POST['submit']) { // display form ?> <table border="0" cellspacing="5" cellpadding="5"> <form action="<? echo $_SERVER['PHP_SELF']; ?>" method="POST"> <tr> <td><b>Username:</b></td> <td><input type="text" name="pop_user"></td> </tr> <tr> <td><b>Password:</b></td> <td><input type="password" name="pop_pass"></td> </tr> <tr> <td><b>POP Server:</b></td> <td><input type="text" name="pop_host"></td> </tr> <tr> <td colspan="2" align="center"><input type="submit" name="submit" value="Get Total Messages!"></td> </tr> </form> </table> <?php } else { // include class definitions include("class.soap_client.php"); // where is the SOAP server $server = "http://mail.service/rpc/server.php"; // arguments $params = array("pop_user" => $_POST['pop_user'], "pop_pass" => $_POST['pop_pass'], "pop_host" => $POST['pop_host']); // instantiate a new client class $client = new soapclient($server); // uncomment next line to see client debug messages // $client->debug_flag = true; /* the call() function packages and transmits a SOAP request to the server, and reads and decodes the response packet it requires four parameters: - the procedure name - an array of arguments, as soapval objects - a namespace - a SOAPAction */ echo $client->call("getTotalPOP3Messages", array(new soapval("pop_params", "SOAPStruct", $params)), "urn:soapserver", "urn:soapserver"); } ?> </body> </html> Creating a SOAP client with SOAPx4 is also fairly easy: Instantiate an object of the class soapclient , pass it to the location of the SOAP server, and use the object's call() method to transmit a remote procedure call to the server and retrieve the response. This response can then be used within your script, in whatever manner you desire . In Listing 8.20, the SOAP response will contain either an integer indicating the number of messages in the user 's mailbox, or (if an error occurred) a fault string and code. More information, together with usage examples and a series of interoperability tests (for both SOAP and WSDL), is available on the project's official web site. Note that, as of this writing, there isn't much documentation available for this class or the methods it exposes. Thus, expect to spend some quality time with the online examples in order to get up and running with your application. |
I l @ ve RuBoard |