Tantalizing Remark on PHP and Web Services

Tweet

Davey Shafik has posted a tantalizing remark on generating WSDL from PHP code, related to some work he’s doing. There’s nothing really to see yet, other than this example;


Crtx_SOAP_AutoDiscover::AutoDiscover(
'some_code.php', 'output_file.wsdl',
'http://example.org/url/of/web/service');
?>

Why is this interesting? The answer takes a little explanation…

If you’ve read web services demystified you’ll know WSDL (Web Services Description Language) is an XML markup that allows you to describe a web service in a manner that a computer can use. When building a client to a web service, it cuts out a lot of manual effort, as you can see by comparing the client1.php vs. client2.php examples, in Zend’s article on the new PHP SOAP Extension.

So for building web service clients, when using WSDL, it’s remarkably simple with PHP (and other dynamically typed languages). The same cannot be said though, when it comes to building servers with PHP, where WSDL generation is concerned.

In WSDL, when describing the arguments a SOAP method accepts and the value it returns, it’s expected that you use XML Schema. XML Schema is “strongly typed” – it has the full range of primitive types (e.g. string, int etc.) as you can see here from which you can build complex types to represent things like objects and hashes (associative arrays). The only thing XML schema doesn’t “do” is indexed arrays, which instead is defined in WSDL.

At this point I could rant about SOAP / WSDL being a debacle, but I won’t, expect for one comment: if you’re ever in the situation of evaluating whether to use SOAP, begin by researching what SOAP stands for (somewhere between “Simple Object Access Protocol” and “Service Oriented Architecture” you may start to get nervous).

Anyway – the problem for dynamically typed languages (those where types are explicitly declared in the source code) is how do you automate the process of generating WSDL from code? As a developer of a web service, ideally you want to be able to write your code in PHP then have some program generate the WSDL for you, to save time, eliminate errors etc.

In languages like Java or C#, where you’re forced to declare types, it’s no problem, for example;


public class Calculator {
public int add(int i1, int i2) {
return i1 + i2;
}
public int subtract(int i1, int i2) {
return i1 - i2;
}
}

The add and subtract methods declare what types of parameter they accept as well as their return values, so it’s simply a matter of using a tool which parses the source code and generates WSDL. But consider the same in PHP;


class Calculator {
function add($i1, $i2) {
return $i1 + $i2;
}
function subtract($i1, $i2) {
return $i1 - $i2;
}
}

Although it’s probably clear to you and me, looking at this code, that the values involved should all be integers, how does a program, analysing this code, work that out?

To make like even more interesting, PHP allows you to accept and return wildly different types, depending on runtime circumstances. For example I could modify the add method above to allow me to add the elements or two arrays;


class Calculator {
function add($i1, $i2) {
if ( is_array($i1) && is_array($i2) ) {
$i1count = count($i1);
if ( $i1count == count($i2) ) {
$sums = array();
for ($i=0; $i < $i1count; $i++) {
$sums[$i] = $i1[$i] + $i2[$i];
}
return $sums;
} else {
return FALSE;
}
} else {
return $i1 + $i2;
}
}

// ...

}

The value returned by the add method now depends on the values I give it. Trying to generate WSDL automatically in this case is clearly going to be a problem - the parser would need to have a very deep understand of PHP's syntax.

As an aside, there are echoes of the same problem when it comes to writing "compilers" which turn PHP into some other, faster, form (see George Schlossnagle's Roadsend PCC, micro-review).

Anyway, watch this space for more on generating WSDL from PHP. Would be great if Davey can pull it off.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Hannes Gassert

    I wonder why you consider WSDL generation to be such a wonderful thing?
    IMO WSDL should be written, not generated. I see a WSDL document as a formal specification that should be written with very little degree of automation and annotated generously – by humans.
    The fact that generating WSDL from (PHP-) code is everything but trivial might be a sign that it’s just not the right thing to do, and that going the other way round is what WSDL was meant for?

  • http://www.lastcraft.com/ lastcraft

    Hi.

    The problem is fundamental as WSDL (read XSchema) is the most strongley typed system on the planet. For example you can have sparse arrays or dense arrays. How are you going to figure that one out even in Java? You either have WSDL types in your code (not a bad idea) or you generate the server code from the user written WSDL (an even better idea). I would really like to be able to generate a PHP server from the WSDL that takes a plug-in class for each method. Is anyone doing that?

    yours, Marcus

  • http://www.phppatterns.com HarryF

    I wonder why you consider WSDL generation to be such a wonderful thing? IMO WSDL should be written, not generated. I see a WSDL document as a formal specification that should be written with very little degree of automation and annotated generously – by humans. The fact that generating WSDL from (PHP-) code is everything but trivial might be a sign that it’s just not the right thing to do, and that going the other way round is what WSDL was meant for?

    On the one hand I agree. WSDL is also declarative – you declare your web service – and as such makes a good point for focusing design effort. What else makes you argue in this direction?

    On the other hand, adoption of technologies depends alot on who much (or how little) human effort is required to use them. Think the initial reaction to WSDL from many developers was “this is too hard” – that may have changed as it’s become better documented and more tools have become available to help authoring it but was probably a driver, initially, for generating WSDL from code. Also, if you first have to hand code WSDL then code the underlying PHP classes it represents, effort is doubled. You then need to maintain both as your web service API undergoes change. Compared to consuming a web service, via WSDL, as a client, creating a server this way seems like heavy going.

    would really like to be able to generate a PHP server from the WSDL that takes a plug-in class for each method. Is anyone doing that?

    I believe the new PHP SOAP extension allows for this in some form e.g. SoapServer::SoapServer. I’ve also tried similar by transforming WSDL to PHP with XSLT (which you’ve seen ;)) here. The more I think about it though, the more it seems like the approach used by WACT’s template engine would be well suited to turning WSDL into a server – you could probably even do it with the engine as it stands today by writing tags for WSDL markup.