PHP: Exposing web services - Part 2

December 11, 2010 by PHP  

In part 1 of this post, we had a quick look at how to expose webservices using the NuSphere Soap Library.

PHP 5 does however have support (in the form of an extension) for SOAP services - which should be superior performance wise (C++ based etc) to the NuSphere implementation.

There is a little hiccup though, we are required to provide a WSDL file to make this process work (consumption/exposion wise). Now instead of explaining the tedious details of how to write the required XML, we're simply going to use the WSDL generated from the NuSphere library in the first post (e.g. index.php?wsdl).

Observe the following snippet:

$server = new SoapServer("definitions.wsdl");
$server->addFunction(SOAP_FUNCTIONS_ALL);
$server->handle();

function test($name)
{
	return "Hello $name";
}

// other functions omitted

  • Save the generated WSDL to definitions.wsdl, and pass it to the SoapServer Class.
  • The SOAP_FUNCTIONS_ALL constant tells the class to add/register all functions defined within the WSDL - we're also able to simply register specific functions
    e.g. $server->addFunction("test");

Alternatively one can set a class thats responsible for handling the requests/functions defined within the WSDL.
class Tester
{
	public function test($name)
	{
		return "Hello $name";
	}
	
	// other functions omitted
}

$server = new SoapServer("definitions.wsdl");
$server->setClass("Tester");
$server->handle();

Note that we can make the class instance persistent as well - useful if we're going to call multiple methods.

Observe:
class Tester
{
	public $name;
	
	public function test($name)
	{
		if ($name != "")
		{
			$this->name = $name;
			return "Hello $name";
		}
		else
		{
			return 'Hello '.$this->name;
		}		
	}
}

//ini_set("soap.wsdl_cache_enabled", 0); 
//ini_set("session.auto_start", 0); 
//ini_set("session.use_cookies", 1);
//session_start();

$server = new SoapServer("definitions.wsdl");
$server->setClass("Tester");
$server->setPersistence(SOAP_PERSISTENCE_SESSION); 
$server->handle();

In the preceding snippet you will notice four lines that are commented out, now while doing research I found a number of sites that stated that it is required to start sessions etc in order to enable persistence.

However while doing testing (on my linux & windows dev environments), it persisted fine without needing any of those commented out lines of code (perhaps I am missing the point - I can be wrong, someone?), it seems to be enough to simply use
$server->setPersistence(SOAP_PERSISTENCE_SESSION).

Something else I noticed in regards to persistence, while attempting to consume the service using .NET (something which might provide us with a clue to how the persistence actually works), is that persistence failed in .NET while it worked fine using PHP.

The reason being that we need to enable cookies for those requests in our .NET based code.

When consuming the service using the older .NET 2.0 based webservice tech, we need to instantiate a cookie container, e.g.
com.example.www.TestService t = new com.example.www.TestService();
t.CookieContainer = new System.Net.CookieContainer();

When using WCF we don't have a CookieContainer property like seen in the older model, instead we need to set the allowCookies attribute within our settings (e.g. web.config/app.config etc) file.

<system.serviceModel>
	<bindings>
		<basicHttpBinding>
		<binding name="TestServiceBinding" allowCookies="true"

In conclusion I feel this is an useful and simple class to use, except for the lack of WSDL generation - which isn't much of a problem in my opinion - would however be nice if we didn't have to rely on other components/tools or write the WSDL ourselves.

It should be fairly simple to derive our WSDL definition from our handling class - perhaps something I can look at in a future post.

Enjoy.


Leave a Comment