PHP: Exposing web services - Part 2
December 11, 2010 by
Christoff Truter
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.