Error establishing a SOAP connection to a WSDL service in PHP - php

I am trying to connect a wsdl service. Other methods don't work without login. But when I tried the login I got a httpheaders error. My wsdl link : http://dgpysws.teias.gov.tr/dgpys/services/EVDServis?wsdl
when i look this link=
http://dgpysws.teias.gov.tr/dgpys/services/EVDServis.wsdl
<xs:element name="login">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="loginMessage" nillable="true" type="dgp:LoginMessage"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="LoginMessage">
<xs:sequence>
<xs:element minOccurs="0" name="Password" nillable="true" type="dgp:StringValue"/>
<xs:element minOccurs="0" name="UserName" nillable="true" type="dgp:StringValue"/>
</xs:sequence>
</xs:complexType>
Here is my php code;
<?php
// Turn up error reporting
ini_set ("display_errors", "1");
error_reporting (E_ALL|E_STRICT);
// Turn off WSDL caching
ini_set ('soap.wsdl_cache_enabled', 0);
$Password = 'deneeme';
$UserName = 'demnenee';
$search_query = new StdClass();
$search_query->oLoginRequest = new StdClass();
$search_query->oLoginRequest->Password = $Password;
$search_query->oLoginRequest->Username = $UserName;
echo "Setting up SOAP options\n";
$soap_options = array(
'trace' => 1, // traces let us look at the actual SOAP messages later
'exceptions' => 1 );
$wsdl = "http://dgpysws.teias.gov.tr/dgpys/services/EVDServis?wsdl";
echo "Checking SoapClient exists\n";
echo '<br>';
if (!class_exists('SoapClient'))
{
die ("You haven't installed the PHP-Soap module.");
}
echo "Creating webservice connection to $wsdl\n";
$webservice = new SoapClient($wsdl,$soap_options);
try {
$result = $webservice->login($search_query);
// perform some logic, output the data to Asterisk, or whatever you want to do with it.
} catch (SOAPFault $f) {
// handle the fault here
echo 'Hata:' . $f;
}
echo "Script complete\n\n";
?>
I am getting this error when run php file;
Setting up SOAP options Checking SoapClient exists
Creating webservice connection to http://dgpysws.teias.gov.tr/dgpys/services/EVDServis?wsdl Hata:SoapFault exception: [HTTP] Error Fetching http headers in C:\xampp\htdocs\test\pmum.php:36 Stack trace: #0 [internal function]: SoapClient->__doRequest('__call('login', Array) #2 C:\xampp\htdocs\test\pmum.php(36): SoapClient->login(Object(stdClass)) #3 {main}Script complete

$client = new SoapClient("http://dgpysws.teias.gov.tr/dgpys/services/EVDServis.wsdl");
$p1->loginMessage->UserName->v = "Deneme";
$p1->loginMessage->Password->v = "Deneme";
$deneme = $client->login($p1);
var_dump($deneme);
worked for me!

Related

How can I add custom elements to the detail section of a SoapFault using PHP's SOAP library

I am building a service against Sonos' Music API (SMAPI). Sometimes I have to send back a response in the following format:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>Client.NOT_LINKED_RETRY</faultcode>
<faultstring>Link Code not found retry...</faultstring>
<detail>
<ExceptionInfo>NOT_LINKED_RETRY</ExceptionInfo>
<SonosError>5</SonosError>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
I am building my service using the PHP SOAP library and for the above response I tried throwing a SoapFault like this:
throw new SoapFault('Client.NOT_LINKED_RETRY', 'Link Code not found retry...');
But when I try this the response that is sent back looks like this:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>Client.NOT_LINKED_RETRY</faultcode>
<faultstring>Link Code not found retry...</faultstring>
<detail>
<SonosError/>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Notice that there is no ExceptionInfo and that SonosError is empty. Is it possible to set ExceptionInfo and SonosError using SoapFault? I tried all kinds of things, but couldn't get it working, so as a work around I am doing this now:
http_response_code(500);
header("Content-type: text/xml");
$ret = '<?xml version="1.0" encoding="UTF-8"?>'."\n";
$ret .= '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">';
$ret .= '<SOAP-ENV:Body>';
$ret .= '<SOAP-ENV:Fault>';
$ret .= '<faultcode>Client.NOT_LINKED_RETRY</faultcode>';
$ret .= '<faultstring>Link Code not found retry...</faultstring>';
$ret .= '<detail>';
$ret .= '<ExceptionInfo>NOT_LINKED_RETRY</ExceptionInfo>';
$ret .= '<SonosError>5</SonosError>';
$ret .= '</detail>';
$ret .= '</SOAP-ENV:Fault>';
$ret .= '</SOAP-ENV:Body>';
$ret .= '</SOAP-ENV:Envelope>'."\n";
echo $ret; exit;
Not sure if it's relevant but the WSDL can be found here.
Update: when I try the suggestion below like this:
$detail = new StdClass();
$detail->SonosError = 5;
$detail->ExceptionInfo = 'NOT_LINKED_RETRY';
throw new SoapFault(
'Client.NOT_LINKED_RETRY',
'Link Code not found retry...',
NULL,
$detail
);
I get:
<detail>
<customFault>
<SonosError>5</SonosError>
<ExceptionInfo>NOT_LINKED_RETRY</ExceptionInfo>
</customFault>
</detail>
This is almost what I need, except for <customFault> tag. Is there a way to get rid of it and have SonosError and ExceptionInfo in <detail> directly?
The fact that you don't see the ExceptionInfo tag is because it is not defined in the wsdl. On the other hand SonosError is defined.
First thing first, in order to fill the SonosError you have to pass the arguments.
From here you can see that the constructor has more parameters
SoapFault('code', 'string', 'actor', 'detail', 'name', 'header');
In order to pass the SonosError call it like this
$detail = new StdClass();
$detail->SonosError = 5;
throw new SoapFault('Client.NOT_LINKED_RETRY', 'Link Code not found retry...', null, $details);
As for the ExceptionInfo, the wsdl must be changed. As it is now, the details tag is represented by this sections
<wsdl:message name="customFault">
<wsdl:part name="customFault" element="tns:SonosError"/>
</wsdl:message>
<xs:element name="SonosError" type="xs:int"/>
If you change the above sections with these, you will have what you need.
<wsdl:message name="customFault">
<wsdl:part name="customFault" type="tns:customFaultType" />
</wsdl:message>
<xs:complexType name="customFaultType">
<xs:sequence>
<xs:element name="SonosError" type="xs:int"/>
<xs:element name="ExceptionInfo" type="xs:string"/>
</xs:sequence>
</xs:complexType>
And of course you add the parameter and the array becomes like this
$detail = new StdClass();
$detail->SonosError = 5;
$detail->ExceptionInfo = 'NOT_LINKED_RETRY';

SOAP WSDL PHP client connecting to .Net Server

I need to integrate a web service, and its being like to days, and the closest I get is the following, maybe some of you have more experience than me in this kind of web service.
The XML request I need to generate is the following
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v2="http://v2.services.cangooroo.net/" xmlns:can="Cangooroo.Webservice.V2">
<soapenv:Header/>
<soapenv:Body>
<v2:getCityData>
<v2:credentialClient>
<can:UserName>?</can:UserName>
<can:Password>?</can:Password>
</v2:credentialClient>
<v2:countryId>US</v2:countryId>
</v2:getCities>
</soapenv:Body>
</soapenv:Envelope>
My PHP code
$client = new SoapClient("http://v2.cangooroo.net/ws/2013/common_a.asmx?WSDL", array(
"trace" => 1,
"compression" => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP,
));
$login = array();
$login[] = new SoapVar('*', XSD_STRING, null, null, 'UserName', 'Cangooroo.Webservice.V2' );
$login[] = new SoapVar('*', XSD_STRING, null, null, 'Password', 'Cangooroo.Webservice.V2' );
$rest = array();
$rest[] = new SoapVar($login, SOAP_ENC_OBJECT, null, null, 'credentialClient' );
$rest[] = new SoapVar('US', XSD_STRING, null, null, 'countryId');
$options = array('location' => 'http://v2.cangooroo.net/ws/2013/common_a.asmx');
try {
$resp = $client->__soapCall('getCityData', $rest, $options);
print_r($resp);
echo "Request:<pre>" . htmlentities($client->__getLastRequest()) . "</pre>";
}catch (SoapFault $e){
echo "REQUEST:<pre>" . htmlentities($client->__getLastRequest()) . "</pre>";
/*print_r($e);*/
The actual xml the PHP code above generates
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="Cangooroo.Webservice.V2" xmlns:ns2="http://ws_2013.services.cangooroo.net/">
<SOAP-ENV:Body>
<ns2:getCityData>
<ns1:UserName>*</ns1:UserName>
<ns1:Password>*</ns1:Password>
</ns2:getCityData><countryId>US</countryId></SOAP-ENV:Body></SOAP-ENV:Envelope>
Iam not really sure if this is the best way to do it, but I tryed others, with __soapCall,
__doRequest, this last one I got the soapClient php core class extended (as a try) to connect, and nothing seems to work. Pls, I could use a little help here. Tks guys.
If you check the wsdl file in http://v2.cangooroo.net/ws/2013/common_a.asmx?WSDL you can see the definition of the getCityData
<s:element name="getCityData">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="credential" type="s1:ClientCredential"/>
<s:element minOccurs="0" maxOccurs="1" name="countryId" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
the operation getCityData has a credential parameter, not a credentialClient that is what you have in the code that you posted. I've tried with this code:
$wsdlAddress = "http://v2.cangooroo.net/ws/2013/common_a.asmx?WSDL";
$options = array(
"soap_version" => SOAP_1_2,
"cache_wsdl" => WSDL_CACHE_NONE,
"exceptions" => false
);
$webServiceClient = new SoapClient($wsdlAddress, $options);
$requestData = array(
"countryId" => "US",
"credential" => array(
"UserName" => "username",
"Password" => "Password",
),
);
$response = $webServiceClient->__soapCall("getCityData", array("getCityData" => $requestData));
echo "<h2>getCityData Operation Test:</h2>";
echo "<pre>";
print_r($response);
echo "</pre>";
in the response i can see Err: Login_Fail - Invalid user or password., i think i'm getting a valid response. Try with my code and adapt it to your needs.
Happy coding

PHP/SOAP response dataset empty

I'm attempting to get data from a Web Service using PHP/SOAP and the response dataset is always empty. I believe that the issue lays in how I set the dsParams parameter.
This is the Web Service URL
If I use SoapUI and send this request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:max="http://www.maxhire.net/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<soapenv:Header>
<max:AuthHeader>
<!--Optional:-->
<max:DatabaseName>Name</max:DatabaseName>
<!--Optional:-->
<max:SecurityKey>Key</max:SecurityKey>
</max:AuthHeader>
</soapenv:Header>
<soapenv:Body>
<max:ExecuteCustomStoredProcedureGetResults>
<max:strProcName>JobPostings</max:strProcName>
<max:dsParams>
<xs:schema id="NewDataSet" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Table">
<xs:complexType>
<xs:sequence>
<xs:element name="ParamName" type="xs:string" minOccurs="0"/>
<xs:element name="ParamValue" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
</max:dsParams>
</max:ExecuteCustomStoredProcedureGetResults>
</soapenv:Body>
</soapenv:Envelope>
I get a desired result.
Each web method that is called using SOAP must pass appropriate security credentials. These credentials must be specified in the SOAP header as DatabaseName and SecurityKey. This part is working correctly.
According to the documentation:
About dsParams
A few things to note about the dsParams dataset that you must pass to use either of these functions (e.g. ExecuteCustomStoredProcedureGetResults):
Even if you have no parameters, you must pass a dataset object that contains one initialized tabled.
If you do have parameters, you must have two columns in that table that are named “ParamName” and “ParamValue”.
Each parameter should be its own row in the table with its name in the first column and value in the second.
Note: I do not have parameters.
Below is an example of one of many ways I’ve attempted to approach this task. It is the closest that I can get without getting errors.
$client = new SoapClient('https://www.maxhire.net/MaxHireAPI/UserServices.asmx?wsdl',array('trace' => TRUE));
$header = new SoapHeader(
'http://www.maxhire.net/',
'AuthHeader',array(
'DatabaseName' => 'Name',
'SecurityKey' => 'Key'
),
false
);
$client->__setSoapHeaders($header);
try {
$jobs = new stdClass();
$jobs->strProcName = 'JobPostings';
$jobs->NewDataSet = new stdClass();
$jobs->NewDataSet->Table = new stdClass();
$jobs->NewDataSet->Table->ParamName = '';
$jobs->NewDataSet->Table->ParamValue = '';
$result = $client->ExecuteCustomStoredProcedureGetResults($jobs);
echo "<pre>\n";
var_dump($result);
echo "</pre>\n";
}
catch(SoapFault $soapfault){
echo "<pre>\n";
var_dump($soapfault);
echo "</pre>\n";
}
The following is the response that I get:
object(stdClass)#7 (1) {
["ExecuteCustomStoredProcedureGetResultsResult"]=>
object(stdClass)#8 (2) {
["schema"]=>
string(323) "<xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="NewDataSet"><xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"><xs:complexType><xs:choice minOccurs="0" maxOccurs="unbounded"/></xs:complexType></xs:element></xs:schema>"
["any"]=>
string(127) "<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"/>"
}
}
echo "Request:\n" . $client->__getLastRequest() . "<br />\n";
Request:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.maxhire.net/">
<SOAP-ENV:Header>
<ns1:AuthHeader>
<ns1:DatabaseName>Name</ns1:DatabaseName>
<ns1:SecurityKey>Key</ns1:SecurityKey>
</ns1:AuthHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:ExecuteCustomStoredProcedureGetResults>
<ns1:strProcName>JobPostings</ns1:strProcName>
</ns1:ExecuteCustomStoredProcedureGetResults>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
echo "Response:\n" . $client->__getLastResponse() . "<br />\n";
Response:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ExecuteCustomStoredProcedureGetResultsResponse xmlns="http://www.maxhire.net/">
<ExecuteCustomStoredProcedureGetResultsResult>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded" />
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" />
</ExecuteCustomStoredProcedureGetResultsResult>
</ExecuteCustomStoredProcedureGetResultsResponse>
</soap:Body>
</soap:Envelope>

passing multiple WSDL header variables to SOAP server

I am using SOAP web services for the first time and i am having a problem in calling the SOAP server. I searched through WSDL SOAP request not i am not able to solve my problem. This is the snippet of my WSDL
<s:complexType name="VerHeader">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="HD1" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="HD2" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="HD3" type="s:string"/>
</s:sequence>
<s:anyAttribute/>
</s:complexType>
I have to send username, password and some ID in these HD1, HD2 and HD3 variables. I have also tried these links Passing a PHP array in a SOAP call and Sending a Soap Header with a WSDL Soap Request with PHP
Here is what i have tried but not working, every time i run my code it send failure message, can you figure it out what's wrong with my code or my logic?
$soap = new SoapClient("http://example.com/verifyrecord.asmx?WSDL");
$header = array('HD1'=>'000000023','HD2'=>'val2','HD3'=>'val2');
$header = new SoapHeader('http://www.example.com/', 'VerHeader ', $header);
$soap->__setSoapHeaders(array($header));
Solved the problem. I solved it not by using php functions but creating an xml file manually and sending it to the soap server. I've posted an example of my answer so that it might be helpful to others. Thanks all for the help.
// the xml to send
$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:Header>
<VerHeader xmlns="http://www.example.com/">
<HD1>000000000117</HD1>
<HD1>user</HD1>
<HD1>password</HD1>
</VerHeader>
</soap:Header>
<soap:Body>
<m:VerifyTransaction xmlns:m="http://www.example.com/">
<m:object1>45344</m:object1>
<m:object2>5545437</m:object2>
</m:VerifyTransaction>
</soap:Body>
</soap:Envelope>';
// build your http request
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => "Content-type: text/xml\r\n",
'validateRequest'=>false,
'content' => $xml,
'timeout' => 10,
),
));
// send it
echo $xmlstring = file_get_contents('http://example.com/VerifyThis/VerifyThis.asmx?wsdl', false, $context);
shouldn't this
new SoapHeader('http://www.example.com/', 'VerHeader ', $header);
be
new SoapHeader('http://www.example.com/verifyrecord', 'VerHeader ', $header);
try like this i did used this for my uk mail api .. and it worked
<?php
$LoginWebRequest = new stdClass();
$LoginWebRequest->Username = 'xxx cant show here xxx';
$LoginWebRequest->Password = 'xxx cant show here xxx';
//echo "<pre>"; print_r($LoginWebRequest); "</pre>"; exit;
$Login = new stdClass();
$Login->loginWebRequest = $LoginWebRequest;
//echo "<pre>"; print_r($Login); "</pre>"; exit;
$soapClient = new SoapClient('https://qa-api.ukmail.com/Services/UKMAuthenticationServices/UKMAuthenticationService.svc?wsdl');
$LoginResponse = $soapClient->Login($Login);
?>

Accessing elements of this xml

<wsdl:definitions targetNamespace="http://www.webserviceX.NET/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://www.webserviceX.NET/">
<s:element name="ConversionRate">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="FromCurrency" type="tns:Currency"/>
<s:element minOccurs="1" maxOccurs="1" name="ToCurrency" type="tns:Currency"/>
</s:sequence>
</s:complexType>
</s:element>
<s:simpleType name="Currency">
<s:restriction base="s:string">
<s:enumeration value="AFA"/>
<s:enumeration value="ALL"/>
<s:enumeration value="DZD"/>
<s:enumeration value="ARS"/>
I am trying to get at all of the elements in enumeration but can't seem to get it right. This is homework so please no full solutions, just guidance if possible.
$feed = simplexml_load_file('http://www.webservicex.net/CurrencyConvertor.asmx?WSDL');
foreach($feed->simpleType as $val){
$ns s = $val->children('http://www.webserviceX.NET/');
echo $ns_s -> enumeration;
}
What am I doing wrong?
thanks
The following works with PHP 5.2:
$feedUrl = 'http://www.webservicex.net/CurrencyConvertor.asmx?WSDL';
$feed = simplexml_load_file($feedUrl);
$feed->registerXPathNamespace('s', 'http://www.w3.org/2001/XMLSchema');
foreach( $feed->xpath('//s:enumeration/#value') as $enumNode) {
echo $enumNode, PHP_EOL;
}
print_r( $feed->getDocNamespaces() );
Another approach would be to use the DOM extension:
$feed = new DomDocument;
$feed->load('http://www.webservicex.net/CurrencyConvertor.asmx?WSDL');
$nodes = $feed->getElementsByTagNameNS(
'http://www.w3.org/2001/XMLSchema',
'enumeration');
foreach( $nodes as $node ) {
echo $node->getAttribute('value'), PHP_EOL;
}

Categories