Search code examples
phpsoapnusoap

PHP / SOAP - trying to learn, but having a problem with implementation


I'm trying to teach myself SOAP, just to extend my skillset a bit, but I've hit a wall and I was wondering if a kind developer out there can help?

I've set up my server thus:

http://www.domain1.com/server.php

<?php
// Pull in the NuSOAP code
require_once('soap/nusoap.php');
// Create the server instance
$server = new soap_server();
// Initialize WSDL support
$server->configureWSDL('hellowsdl', 'urn:hellowsdl');
// Register the method to expose
$server->register('hello',    // method name
 array('name' => 'xsd:string'),  // input parameters
 array('return' => 'xsd:string'), // output parameters
 'urn:hellowsdl',     // namespace
 'urn:hellowsdl#hello',    // soapaction
 'rpc',        // style
 'encoded',       // use
 'Says hello to the caller'   // documentation
);
// Define the method as a PHP function
function hello($name) {
        return 'Hello, ' . $name;
}
// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>

And now I've tried to set up a client on a seperate server:

http://www.domain2.com/client.php

<?php
// Pull in the NuSOAP code
require_once('soap/nusoap.php');
// Create the client instance
$client = new soapclient('http://domain.com/server.php?wsdl', true);
// Check for an error
$err = $client->getError();
if ($err) {
 // Display the error
 echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
 // At this point, you know the call that follows will fail
}
// Call the SOAP method
$result = $client->call('hello', array('name' => 'Scott'));
// Check for a fault
if ($client->fault) {
 echo '<h2>Fault</h2><pre>';
 print_r($result);
 echo '</pre>';
} else {
 // Check for errors
 $err = $client->getError();
 if ($err) {
  // Display the error
  echo '<h2>Error</h2><pre>' . $err . '</pre>';
 } else {
  // Display the result
  echo '<h2>Result</h2><pre>';
  print_r($result);
 echo '</pre>';
 }
}
// Display the request and response
echo '<h2>Request</h2>';
echo '<pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
echo '<h2>Response</h2>';
echo '<pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';
// Display the debug messages
echo '<h2>Debug</h2>';
echo '<pre>' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '</pre>';
?>

But I can't get the fecking thing working. The server displays just fine - wdsl output the lot. But the client can't/won't connect and complete the transaction. I get this message:

Warning: SoapClient::SoapClient() expects parameter 2 to be array, boolean given in /home/public_html/slidebank_soap_client.php on line 5

Fatal error: Uncaught SoapFault exception: [Client] SoapClient::SoapClient() [<a href='soapclient.soapclient'>soapclient.soapclient</a>]: Invalid parameters in /home/soap/slidebank_soap_client.php:5 Stack trace: #0 /home/soap/slidebank_soap_client.php(5): SoapClient->SoapClient('http://testing....', true) #1 {main} thrown in /home/public_html/soap/slidebank_soap_client.php on line 5

And this is where I'm stumped...

Any ideas?

H


Solution

  • I used to be a fan of using nusoap with PHP3/4 (i.e. back when PHP didn't have a built in SOAP client) but with PHP5's SOAP Client I find I don't have any need for nusoap these days.

    An advantage PHP5's built in SOAP client is that it's much cleaner and simplier to implement and so mention it as it might be helpful to you (I know some choose to use nusoap instead, but a lot of people apparently just aren't aware it's there in PHP5 as a lot of "HOWTO" guides are out of date and neglect to mention it).

    Example usage:

    ini_set("soap.wsdl_cache_enabled", "1"); // Set to zero to avoid caching WSDL
    $soapClient = new SoapClient('http://www.example.com/webservices/HelloWorldService/?wsdl");     
    $result = $soapClient->HelloWorldMethod(array('string' => "hello!"));    
    print_r($result);
    

    On a note regarding service types:

    When it comes to a SOAP service, ideally you want to implement a Document/Literal service, rather than an RPC/Encoded service, as RPC/Encoded is a difficult format to work with and for that reason has been deprecated by the WS-I in favour of Document/Literal (which is both much easier to work with and more logical in design).

    To start with, you might want to try implementing a client against an existing service if you can - that way you know it's at least working properly, which might save you a few headaches.

    Unfortunately - while it's excellent at consuming them - PHP doesn't have particularly great support for serving Document/Literal services. There is at least one third party nusoap-like library for this IIRC, but it didn't quite cut it for me.

    (If any of this is outdated, corrections welcome.)