Your NuSoap client doesn't work and you try to consume a .NET document/literal web service? No stress, here is a tip to take full control of the SOAP message you send (because, obviously, we are going to write it "by hand", I love that! ;-) . In fact it is not a real workaround, but you will be able to send a pre-formatted SOAP message using some of the function defined in nusoap.php. Here we will use another web service (almost on-line 24/24) to test this case. We are going to consume a not-so-old version of a .NET web service: Infobel web service. You can use this service as a phone directory service demo. You have to send a login/password and some name and city and the service return a list of person matching your data. So we are going to search for Mr. Durand in Brussels, Belgium (Europe)...
![]() | Important note |
|---|---|
The data returned by this web service are obsolete, are from a few years ago and can only be used for demo and testing purpose. |
First a look at the wsdl, and more particularly at the Search() method (the only one ;-). This remote procedure take an object as param: inputQuery. Object composed by a list of field, and we will have to fill some of them, using sometime constant enumeration like Countries, Services...(See a wsdl excerpt below)
<s:schema elementFormDefault="qualified" targetNamespace="http://www.infobel.com/WebService/">
<s:element name="Search">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="inputQuery" type="s0:CQuery" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="CQuery">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="login" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="password" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="country" type="s0:Countries" />
<s:element minOccurs="1" maxOccurs="1" name="service" type="s0:Services" />
<s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="FirstName" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Street" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="bldnum" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="City" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Zip" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Phone" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Area" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Category" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="XCoord" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="YCoord" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Range" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="PageStep" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Language" type="s0:Lang" />
<s:element minOccurs="1" maxOccurs="1" name="CoordType" type="s0:CoordTypes" />
</s:sequence>
</s:complexType>
<s:simpleType name="Countries">
<s:restriction base="s:string">
<s:enumeration value="aeCountryBE" />
<s:enumeration value="aeCountryFR" />
<s:enumeration value="aeCountryDK" />
<s:enumeration value="aeCountryUK" />
<s:enumeration value="aeCountryES" />
<s:enumeration value="aeCountryNotAv" />
</s:restriction>
</s:simpleType>
<s:simpleType name="Services">
<s:restriction base="s:string">
<s:enumeration value="aeSrvStandard" />
<s:enumeration value="aeSrvExtended" />
<s:enumeration value="aeSrvScore" />
</s:restriction>
</s:simpleType>
<s:simpleType name="Lang">
<s:restriction base="s:string">
<s:enumeration value="aeLangFrench" />
<s:enumeration value="aeLangDutch" />
<s:enumeration value="aeLangGerman" />
<s:enumeration value="aeLangEnglish" />
<s:enumeration value="aeLangSpanish" />
</s:restriction>
</s:simpleType>
<s:simpleType name="CoordTypes">
<s:restriction base="s:string">
<s:enumeration value="aeCTLamb2" />
<s:enumeration value="aeCTWGS" />
</s:restriction>
</s:simpleType>So let's try to compose by our-self the content of the body of our SOAP message to query this web service, we will use NuSoap to achieve the job:
<!-- we must use the targetnamespace this way, this .NET web service doesn't like the namespace prefix generated automatically by NuSoap--> <Search xmlns="http://www.infobel.com/WebService/"> <!-- nothing really difficult here, just follow the wsdl, or, use the tool TcpTunnelGui with a working client, or see the documentation generated by the .NET web service on-line--> <inputQuery> <!-- we just have to specify the minOccurs="1" for our SOAP message to be accepted as a valid message by the web service. Add the other field, so the server will return some results... --> <login>infobel</login> <password>test</password> <country>aeCountryBE</country> <service>aeSrvStandard</service> <Name>durand</Name> <City>bruxelles</City> <Zip></Zip> <XCoord>0</XCoord> <YCoord>0</YCoord> <Range>0</Range> <PageStep>5</PageStep> <Language>aeLangFrench</Language> <CoordType>aeCTWGS</CoordType> </inputQuery> </Search>
We plan here to use some function available in nusoap.php to make the call. Find the PHP code below to finalize our query:
Example 2-3. PHP code to query a web service using a pre-formated SOAP message
require_once('nusoap.php');
// define the soapaction as found in the wsdl
$soapaction = "http://www.infobel.com/WebService/Search";
// endpoint address
$wsdl = "http://hal.kapitol.com/infobelservices/service1.asmx";
$namespace = "http://www.infobel.com/WebService/";
$client = new soapclient($wsdl);
// you will find the serializeEnvelope() prototype by making a search in nusoap.php
$mysoapmsg = $client->serializeEnvelope('<Search xmlns="http://www.infobel.com/WebService/"><inputQuery>
<login>infobel</login>
<password>test</password>
<country>aeCountryBE</country>
<service>aeSrvStandard</service>
<Name>durand</Name>
<City>bruxelles</City>
<Zip></Zip>
<XCoord>0</XCoord>
<YCoord>0</YCoord>
<Range>0</Range>
<PageStep>5</PageStep>
<Language>aeLangFrench</Language>
<CoordType>aeCTWGS</CoordType>
</inputQuery></Search>','',array(),'document', 'literal');
/* Send the SOAP message and specify the soapaction */
$response = $client->send($mysoapmsg, $soapaction);
if ($client->fault) {
echo '<h3>Fault</h3><pre>';
print_r($response);
echo '</pre>';
}
echo "<p>SOAP query</p>";
echo '<pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
echo "<p>SOAP response</p>";
echo '<pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';
// start to use the result by following the structure of the SOAP response
// first extract the SearchResult
$searchresult = $response["SearchResult"];
// then you can access the Status message
echo "Status message: ".$searchresult["Status"];
// continue with the Result level
$result = $searchresult["Result"];
// wich allow access to NumRecs (number of record found)
echo "<br>Record found: ".$result["NumRecs"];
// extract the collection of record (object collRecord)
$collrecord = $result["collRecord"];
foreach ($collrecord["CRecord"] as $record){
echo "<br>Name: ".$record["Name"];
echo "<br>Address: ".$record["Address"];
//...... and so on.....
}For a NuSoap client trying to access a .NET document/literal web service, we need to make a part of the job by hand. The interesting part here is for the use of the nusoap function serializeEnvelope.
![]() | ![]() | ![]() |
| Make a SOAP client using PHP and NuSoap. | ![]() My home page Index | Make a SOAP client with Perl and SOAP::Lite |