Implement SOAP 1.1 in php - php

The following is a sample SOAP 1.1 request and response
POST /DEMOWebServices2.8/service.asmx HTTP/1.1
Host: api.efxnow.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "https://api.efxnow.com/webservices2.3/DealRequestAtBest"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<Authenticator xmlns="https://api.efxnow.com/webservices2.3">
<ApplicationName>string</ApplicationName>
<IPAddress>string</IPAddress>
<UserID>string</UserID>
<MachineName>string</MachineName>
</Authenticator>
</soap:Header>
<soap:Body>
<DealRequestAtBest xmlns="https://api.efxnow.com/webservices2.3">
<UserID>string</UserID>
<PWD>string</PWD>
<Pair>string</Pair>
</DealRequestAtBest>
</soap:Body>
</soap:Envelope>
Response -
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<DealRequestAtBestResponse xmlns="https://api.efxnow.com/webservices2.3">
<DealRequestAtBestResult>
<Success>boolean</Success>
<ErrorDescription>string</ErrorDescription>
<ErrorNumber>int</ErrorNumber>
<Confirmation>string</Confirmation>
<ConfirmationNumber>string</ConfirmationNumber>
<Rate>double</Rate>
</DealRequestAtBestResult>
</DealRequestAtBestResponse>
</soap:Body>
</soap:Envelope>
i want to know how to make the request and how to handle response if this had to be done in php. i read this but i can't figure out how would __setSoapHeaders() and __call() be implemented in my case. thanks in advance.

There's a SOAP library for PHP, but for a simple exchange you might consider building XML request body as a string and the dispatch it using the curl library function. It's a much more low-level network api, which I at least find easier to use. Note that PHP needs to be compiled --with-curl[=DIR].
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uri);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if ((bool)$proxy) {
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Pragma:','Cache-Control:'));
curl_setopt($ch, CURLOPT_PROXY, $proxy);
}
// Apply the XML to our curl call
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);
$out = curl_exec($ch);
curl_close($ch);
?>

Related

Parse SOAP API using php

I am a beginner at SOAP and have been trying to figure how to get get a proper response when I call the SOAP API. I have tried diff method since last 3 days but still have no idea. I have already tried similar questions like this on stackoverflow but somehow they are not working for me.
I really appreciated your help or response how I may be able to get this done.
Here's the sample request that I should send:
POST /wsror/Form.asmx HTTP/1.1
Host: 10.159.159.1
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://apps.in/wsror/GetAllVill"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetAllVill xmlns="http://apps.in/wsror">
<strTaluka>string</strTaluka>
<Username>string</Username>
<Password>string</Password>
</GetAllVill>
</soap:Body>
</soap:Envelope>
here's the response:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetAllVillResponse xmlns="http://apps.in/wsror">
<GetAllVillResult>dataset</GetAllVillResult>
</GetAllVillResponse>
</soap:Body>
</soap:Envelope>
I have tried fetching response by using below method:
$soapclient = new SoapClient('sensitive info');
$param=array('sensitive info');
$response =$soapclient->GetAllVill($param);
var_dump($response);
and I get below response:
object(stdClass)#2 (1) { ["GetAllVillResult"]=> object(stdClass)#3 (1) { ["any"]=> string(6596) "19200Adco 24000Bandora 3001000600020700Beto 30010tqui 001900Bma 300100060Borim 600019Capar " } }
I have used curls to finally solve this issue.
$url = "http://apps.in/wsror?wsdl";
$xml = '<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetAllVill xmlns="http://apps.in/wsror">
<strTaluka>code</strTaluka>
<Username>Username</Username>
<Password>Password</Password>
</GetAllVill>
</soap:Body>
</soap:Envelope>';
$headers = array(
"Content-type: text/xml",
"Content-length: " . strlen($xml),
"Connection: close",
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$data = curl_exec($ch);
//echo $data;
$doc = new DOMDocument();
$doc->loadXML($data);
and then looped through the required tags.
$VILLAGES = $doc->getElementsByTagName('VILLAGES');
foreach ($VILLAGES as $VILLAGE) {
$VillageName = $VILLAGE->getElementsByTagName('VillageName')->item(0)->nodeValue;
$Village = $VILLAGE->getElementsByTagName('Village')->item(0)->nodeValue;
// $id = $VILLAGE->getElementsByTagName('taluka')->item(0)->nodeValue;
echo '<option value="'.htmlentities($Village, ENT_QUOTES, "UTF-8").'" >'.htmlentities($VillageName, ENT_QUOTES, "UTF-8").'</option> ';
}

PHP & XML - How to generate a soap request in PHP from this XML?

I am completly new to SOAP operations.
I have been provided with an XML document (SOAP) to get some collection points for a shipping method.
From the manual located here:
http://privpakservices.schenker.nu/package/package_1.3/packageservices.asmx?op=SearchCollectionPoint
I can see that I need to use the following SOAP request:
POST /package/package_1.3/packageservices.asmx HTTP/1.1
Host: privpakservices.schenker.nu
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://privpakservices.schenker.nu/SearchCollectionPoint"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<SearchCollectionPoint xmlns="http://privpakservices.schenker.nu/">
<customerID>long</customerID>
<key>string</key>
<serviceID>string</serviceID>
<paramID>int</paramID>
<address>string</address>
<postcode>string</postcode>
<city>string</city>
<maxhits>int</maxhits>
</SearchCollectionPoint>
</soap:Body>
</soap:Envelope>
The thing is that i don't know how to send this as a request using PHP, and how to get the response.
Any help to pinpoint me in the right direction, is much appreciated.
UPDATE
I can read the response data with var_dump. However, I am not able to read individual element data.
I need to read data as below
foreach($parser as $row) {
echo $row->customerID;
echo $row->key;
echo $row->serviceID;
}
If anyone should be interested, i have provided the correct answer:
$soapUrl = "http://privpakservices.schenker.nu/package/package_1.3/packageservices.asmx?op=SearchCollectionPoint";
$xml_post_string = '<?xml version="1.0" encoding="utf-8"?><soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"><soap12:Body><SearchCollectionPoint xmlns="http://privpakservices.schenker.nu/"><customerID>XXX</customerID><key>XXXXXX-XXXXXX</key><serviceID></serviceID><paramID>0</paramID><address>RiksvÅ gen 5</address><postcode>59018</postcode><city>Mantorp</city><maxhits>10</maxhits></SearchCollectionPoint></soap12:Body></soap12:Envelope>';
$headers = array(
"POST /package/package_1.3/packageservices.asmx HTTP/1.1",
"Host: privpakservices.schenker.nu",
"Content-Type: application/soap+xml; charset=utf-8",
"Content-Length: ".strlen($xml_post_string)
);
$url = $soapUrl;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
curl_close($ch);
$response1 = str_replace("<soap:Body>","",$response);
$response2 = str_replace("</soap:Body>","",$response1);
$parser = simplexml_load_string($response2);
following example might help you.
SOAP XML schema
<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.dataaccess.com/webservicesserver/">
<x:Header/>
<x:Body>
<web:NumberToDollars>
<web:dNum>10</web:dNum>
</web:NumberToDollars>
</x:Body>
</x:Envelope>
PHP code
$wsdl = 'http://www.dataaccess.com/webservicesserver/numberconversion.wso?WSDL';
try{
$clinet=new SoapClient($wsdl);
$ver =array("dNum"=>"2002");
$quates=$clinet->NumberToDollars($ver);
var_dump($quates);
}
catch(SoapFault $e)
{
echo $e->getMessage();
}

php soap server return plain response

Actually I create a Soap Proxy in which I get the client request and I need to post the request further to another SOAP server (with c_url).
The response is successfully obtained (as xml with <SOAP-ENV and all others).
The problem is that in my SOAP PROXY I want to return exactly the response and if my server is returning the xml the SOAP Server actually return the XML file wrap up
<SOAP-ENV:Envelope ...>
<SOAP-ENV:Body>
<ns1:loginResponse>
my xml that already contains <soap:Envelope, <soap:Body> and <namesp1:loginResponse>
</ns1:loginResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The question is: How can I make the soap server to return exactly the response that i want without wrapping up with soap envelope and others?
Thanks.
UPDATED:
My soap server:
$server = new SoapServer($myOwnWsdlPath);
$this->load->library('SoapProxy');
$server->setClass('SoapProxy', $params );
$server->handle();
My soap Porxy with c_url:
public function __call($actionName, $inputArgs)
{
//some logic
$target = ...
$url = ..
$soapBody =..
$headers = ..
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $soapBody); // the SOAP request
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch); //soap xml response
curl_close($ch);
file_put_contents('/tmp/SoapCurl.txt', var_export($response, true));
return $response;
}
The response from /tmp/SoapCurl.txt is the correct one:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope ...>
<soap:Body>
<namesp1:loginResponse>
<session_id xsi:type="xsd:string">data</session_id>
</namesp1:loginResponse>
</soap:Body>
</soap:Envelope>
My soap server response is wrong:
<SOAP-ENV:Envelope ...>
<SOAP-ENV:Body>
<ns1:loginResponse>
<soap:Envelope ...>
<soap:Body>
<namesp1:loginResponse>
<session_id xsi:type="xsd:string">correct data</session_id>
</namesp1:loginResponse>
</soap:Body>
</soap:Envelope>
</ns1:loginResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The fix I found was to extend the 'handle' function of SoapServer
Discard the output of SoapServer (with ob_end_clean) and replace it with my data
class MySoapServer extends SoapServer
{
public function handle($soap_request = null)
{
parent::handle();
ob_end_clean();
ob_start();
echo $_SESSION['data'];
}
}

How to do a POST with XML API?

Here we see: https://developers.google.com/youtube/2.0/developers_guide_protocol_comments#Adding_a_comment
I need to do a request with XML API.
POST /feeds/api/videos/VIDEO_ID/comments HTTP/1.1
Host: gdata.youtube.com
Content-Type: application/atom+xml
Content-Length: CONTENT_LENGTH
Authorization: Bearer ACCESS_TOKEN
GData-Version: 2
X-GData-Key: key=DEVELOPER_KEY
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:yt="http://gdata.youtube.com/schemas/2007">
<content>This is a crazy video.</content>
</entry>
What should I use for this?
You can use cURL to do this.
<?php
$data = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:yt="http://gdata.youtube.com/schemas/2007">
<content>This is a crazy video.</content>
</entry>
XML;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'gdata.youtube.com/feeds/api/videos/VIDEO_ID/comments');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER,
array('Content-Type: application/atom+xml',
'Authorization: Bearer ACCESS_TOKEN',
'GData-Version: 2',
'X-GData-Key: key=DEVELOPER_KEY'));
$re = curl_exec($ch);
curl_close($ch);
?>
You'll likely find it easiest to use one of the client libraries rather than do the POST manually, because it will handle header generation, authentication, and tokens for you without a lot of hassle. A list of the client libraries is here:
https://developers.google.com/youtube/code
For example, to do a comment post with the Python client, it would look something like this (assuming you'd gone through the authentication steps, which the clients make pretty simple):
my_comment = 'what a boring test video'
video_id = '9g6buYJTt_g'
video_entry = yt_service.GetYouTubeVideoEntry(video_id=video_id)
yt_service.AddComment(comment_text=my_comment, video_entry=video_entry)
The clients for other languages follow the same structure.

PHP SOAPClient Request Issue

I am trying to call this web service http:// 115. 186. 182.11/csws/Service.asmx?op=SendSMS with following PHP code but it gives me exception Error mate in Script: Server was unable to process request. ---> Object reference not set to an instance of an object.
Will highly appreciate your help on this.
try {
$client = new SoapClient("http://115.186.182.11/csws/Service.asmx?wsdl");
$method = 'SendSMS';
$params = array(
new SoapParam('xxxxx', 'Src_nbr'),
new SoapParam('xxxxxx', 'Password'),
new SoapParam('xxxxx', 'Dst_nbr'),
new SoapParam('xxxxx', 'Mask'),
new SoapParam('Message is test message', 'Message')
);
$result = $client->__call($method,$params);
}
catch(SoapFault $e){
echo "Error mate in Script: " . $e->getMessage();
}
echo "<pre>";
var_dump($result);
echo "</pre>";
$xmlobj = simplexml_load_string($result);
print_r($xmlobj);
FOllowing is the specification...
POST /csws/Service.asmx HTTP/1.1
Host: 115.186.182.11
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/SendBulkSMS"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<SendBulkSMS xmlns="http://tempuri.org/">
<Src_nbr>string</Src_nbr>
<Password>string</Password>
<Dst_nbr>xmlxml</Dst_nbr>
<Mask>string</Mask>
<Message>string</Message>
</SendBulkSMS>
</soap:Body>
</soap:Envelope>
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<SendBulkSMSResponse xmlns="http://tempuri.org/">
<SendBulkSMSResult>
<string>string</string>
<string>string</string>
</SendBulkSMSResult>
</SendBulkSMSResponse>
</soap:Body>
</soap:Envelope>
I followed the below method finally and it is working perfect in production.
$fields = '<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<SendSMS xmlns="http://tempuri.org/">
<Src_nbr>xxxx</Src_nbr>
<Password>123</Password>
<Dst_nbr>xxxxxxxxxx</Dst_nbr>
<Mask>xxxk</Mask>
<Message>Aoa, This is Test. From xxx.</Message>
<TransactionID>11122276</TransactionID>
</SendSMS>
</soap12:Body>
</soap12:Envelope>';
echo $fields;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $postUrl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
curl_setopt($ch, CURLOPT_POSTFIELDS, "$fields");
$response = curl_exec($ch);
curl_close ($ch);
In production the SMS API was using this code and code was exected more than 20 time per seconds and performance is good as-well.

Categories