Since it was always hard to find documentation i ‘ve gathered available noSOAP API documentation source here:
- Getting complex with PHP and NuSOAP
- Programming with NuSOAP
- Programming with NuSOAP Part 2
- Introduction to NuSOAP
- Programming with NuSOAP Using WSDL
- Creating a web service and WSDL using NuSOAP
SOAP Arrays
I had a problem with using arrays with certain WS clients. It seems that nuSOAP uses SOAP array which are deprecated in favor of xml sequences according to WS-I. Here’s a small piece of code to create:
- An array of strings
- A soap structure
- An array of the above structure
$server->wsdl->addComplexType( 'ArrayOfDN', 'complexType', 'array', $soap_compositor, '', array( 'dn' => array('name' => 'dn', 'type' => 'xsd:string', 'minOccurs' => '0', 'maxOccurs' => 'unbounded') ) ); $server->wsdl->addComplexType( 'RoleDesc', 'complexType', 'struct', $soap_compositor, '', array( 'cn' => array('name' => 'cn', 'type' => 'xsd:string'), 'description' => array('name' => 'description', type => 'xsd:string') ) ); $server->wsdl->addComplexType( 'ArrayOfRoleDesc', 'complexType', 'array', $soap_compositor, '', array( 'desc' => array('name' => 'desc', 'type' => 'tns:RoleDesc', 'minOccurs' => '0', 'maxOccurs' => 'unbounded') ) );
$soap_compositor can have a value of ‘all’, ‘sequence’ or ‘choice’. In our case the value is sequence.
UTF-8 encoded values (foreign charsets)
Another thing to keep in mind is UTF-8 encoded values (usually in foreign charsets like greek in my situation). The best approach is to use the iconv() php function to transform native charset (eg ISO-8859-7) to UTF-8 for transport and disable nusoap automatic utf8 decoding. You should also make sure to set the http transport charset to UTF-8 instead of the default iso-8859-1. The corresponding values are:
- var $decode_utf8 = false; in the nusoap_client and nusoap_server classes
- var $soap_defencoding = ‘UTF-8’; in the nusoap_base class
Document/literal instead of RPC/Encoded
Modern web service clients usually request web services to be written in document-literal mode. Thus you should call the configureWSDL() and register() functions this way:
$server->configureWSDL(‘ReaderInterface’,”$url”,false,’document’);
$server->register(‘<function name>’,
array(‘argument’ => ‘xsd:string’),
array(‘retval’ => ‘xsd:string’),
false, #namespace
$url . ‘#<function name>’,
‘document’,
‘literal’,
‘<function documentation>’);
In current nuSOAP version there is no way to omit the namespace attribute in the bindings part of the WSDL. That means that you will probably hit on warning such as:
R2716 WSI-BasicProfile ver. 1.0, namespace attribute not allowed in doc/lit for soapbind:body: “SearchUser”
line 370 of file:/C:/temp/NetBeansProjects/testWSDL3/xml-resources/web-service-references/reader/wsdl/<hostname>/ws/reader.php.wsdl
when attempting to parse the WSDL in your client. For now you have to save the WSDL and remove the namespace attributes by hand. Hopefully the nuSOAP people will have it fixed soon.
SOAP faults
One common problem that you may hit on is to get an error when dissecting a soap fault. The usual fault is something like:
“No NamespaceURI, SOAP requires faultcode content to be a QName”
That means that when creating a soap fault with new soap_fault($faultcode, $faultfactor, $faultstring, $faultdetail) the $faultcode should be something like SOAP-ENV:Client or SOAP-ENV:Server instead of just ‘Client’ or ‘Server’ just as it is described in the class prototype in nusoap.php.
13 comments
Comments feed for this article
March 2, 2009 at 7:15 pm
Mike
Just passing by.Btw, you website have great content!
______________________________
Don’t pay for your electricity any longer…
Instead, the power company will pay YOU!
April 16, 2009 at 3:16 am
Mathew Thomas
Recently for a project involving travelport xml api integration, we badly needed the soap requests to be gzip-ped, since the technical support people suggested.
http://www.php-trivandrum.org/tips/gzip-nusoap-requests.html
May 26, 2009 at 9:04 am
Francesco
Hi,
I can confirm that NuSOAP does handle array generally producing WSDL which does not follow the WS-I BP 1.1 specifications.
So, for example, if you want to consume your NuSOAP webservice with the SAP ERP, you probably will get an error message complaining about the arrayType generated by NuSOAP in the service wsdl (at least, this is my experience :)).
see:
http://www.ws-i.org/Profiles/BasicProfile-1.1.html (WS-I BP 1.1 definitions)
I don’t know if you can teach the NuSOAP library to return/take in input arrays in a WS-I compliant fashion.
Do you have any idea about that? Thanks in advance 🙂
May 26, 2009 at 6:38 pm
Thomas Armstrong
I need to use sequences instead of SOAP arrays. So I used the code as you explain above for declaring the types. But now my service dows not return any data! Can you please post some example on how to do it?
Great!
July 23, 2009 at 2:02 pm
Berlington Barnett
Hi everybody.
I’m looking for a solution about how I can construct a complex array with nusoap to return my data from my ws server like this:
1
myname
mynickname
title-1
author-1
title-2
author-2
title-1
author-1
title-3
author-3
Thank you
August 25, 2009 at 9:11 pm
daniel
Thanks a lot for putting all this together in one place. I ran into some of the links you had, but your compilation was very helpful.
In particular, the information you posted about the soap array and xml sequences alternatives was very useful as I did not see it anywhere else.
Suggestion: change the $soap_compositor variable to something like sequence or all or whatever else so that new people don’t get confused… I know I did. or you can initialize the variable here inside your examples.
Is there a nusoap documentation site somewhere? I would like to see the API for the function calls and maybe also figure out what else is there.
thanks!
October 29, 2009 at 8:46 am
scott
Hi, You seem to know your stuff and im struggling to consume a .net webservice with a php client.
[WebMethod]
public string TestMethod(int id,string[] taxparms) {
return “ID: ” + id + ” PARM: ” + taxparms[0];
}
PHP
$params=array();
$params[“id”]=5;
$params[“taxparms”]=array(“test1″,”test2”);
$result=$client->call(“TestMethod”,$params);
What in the world am i doing wrong. Id is passed correctly, but the taxparms array isnt. Can you help me ? 🙂
January 7, 2010 at 4:31 am
avejidah
Thanks for the post, got me on the right path. The problem I have is when returning an array of structs (like your last example). The xml generated will look like:
Notice that the item type is “xsd:” instead of “tns:RoleDesc”. This causes a fault in my client (I’m using Flex to consume the service) as the client is unable to unmarshall the type. Any way to avoid this?
Thanks!
January 7, 2010 at 4:33 am
avejidah
I guess my xml was eaten in the last post ^^. The xml returned will look like
<return xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType=":[2]">
<item xsi:type="xsd:">
January 14, 2010 at 12:44 am
avejidah
The function above is incorrect an yields invalid SOAP. It should be:
$server->wsdl->addComplexType
(
‘ArrayOfRoleDescs’,
‘complexType’,
‘array’,
‘sequence’,
”,
array(),
array
(
array(‘ref’ => ‘SOAP-ENC:arrayType’,
‘wsdl:arrayType’ => ‘tns:RoleDesc[]’)
),
‘tns:RoleDesc’
);
September 13, 2010 at 8:58 pm
Jon
How do you actually make NuSOAP return the array data as a sequence in the SOAP response?
I understand this:
$server->wsdl->addComplexType(
‘ArrayOfRoleDesc’,
‘complexType’,
‘array’,
$soap_compositor,
”,
array(
‘desc’ => array(‘name’ => ‘desc’, ‘type’ => ‘tns:RoleDesc’,
‘minOccurs’ => ‘0’, ‘maxOccurs’ => ‘unbounded’)
)
);
What do you actually return in the registered function to make an appropriate response when retval => ‘tns:ArrayOfRoleDesc’? Could you give a simple example? I can’t seem to get NuSoap to encode the response value correctly. Do you have to generate the XML yourself and return it?
November 19, 2010 at 2:45 pm
Pazso
Thank you for this useful description.
January 25, 2011 at 8:58 am
daniel
Great point iconv. I used for spanish strings:
iconv(“UTF-8”, “ISO-8859-1”,$line->title));