Using Complex Type with Zend_Soap
To be able to use complex types with Soap requests, they need to be fully defined in the WSDL file. Zend_Soap can automate this process, if you know how to define those complex types.
Let us start without it Zend_Soap's magic and compare it with a fully discovered complex request type afterwards.
First, let's define your classes. Let's assume we have a book collection, and each book can have multiple tags.
Our webservice class looks like this:
By using Zend_Soap and the automagically created WSDL file, the code launching our SOAP server could look like this:
The WSDL (just browse to http:/localhost/soap.php?WSDL=1) does not hold any information about the Book or Tags objects:
The inserted book can be of anyType. This is not really useful as you can imagine.
Now, let's spice things up. The real magic in Zend_Soap is in the autodiscovery mechanism producing the WSDL file. Zend_Soap_AutoDiscover won't know how to use all those variables, unless you define the types with correct docblock information, like this:
The type for $tags is Tag[], Tag comes from the defined class, and [] makes it an array. Note the /**, it's necessary to use 2 asterisks for the Reflection class to identify the docblock.
Now you can use the Book type in your Webservice functions. The insertBook method is annotated like this:
Zend_Soap_Autodiscover has several strategies, you can read the Zend Framework Manual for more information on complex type strategies. We will use Zend_Soap_Wsdl_Strategy_ArrayOfTypeComplex, so Autodiscover can find the Tag array in the Book object. To do so, just update this line:
to this:
The WSDL (download here) will now hold a lot more information. Custom types were added for example:
The insertBookIn message now mentions the type Book. And Book is described in the types container in detail. Web service clients are now able to insert books with all information as required by the service.
Remember, the real magic of the Zend_Soap component lies in Zend_Soap_AutoDiscover. You can even create the WSDL file using Zend_Soap_AutoDiscover and then expose the service using PHP-only methods. You just need an additional classmap to make this possible:
Want to know more? Read more on Web Services and Zend Framework in the Zend Framework Web Services book, available from PHP|Architect and written by Jonas.