Our SOAP request doesn't work because it seems that SOAP is converting our XML string into < and >
$client = new SoapClient("https://some-test-url/xxx.asmx?wsdl", array('trace' => true) );
$soapparams = array (
"UserName" => 'uname',
"Password" => 'pword',
"GroupID" => 1,
"xmlstring" => '
<![CDATA[
<DocumentElement>
<tbl>
<var1>Q</var1>
<var2>W</var2>
<var3>E</var3>
</tbl>
</DocumentElement>
]]>
'
);
$response = $client->__soapCall('functionHere', array($soapparams));
$raw_request_header = $client->__getLastRequestHeaders();
$raw_request_body = $client->__getLastRequest();
$raw_response_body = $client->__getLastResponse();
echo "<br /><br />Raw Request: ";
echo "<code>";
print htmlentities($raw_request_body);
echo "</code>";
Im getting this:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/">
<SOAP-ENV:Body>
<ns1:functionHere>
<ns1:UserName>uname</ns1:UserName>
<ns1:Password>pword</ns1:Password>
<ns1:GroupID>1</ns1:GroupID>
<ns1:xmlstring>
<![CDATA[
<DocumentElement>
<tbl>
<var1>Q</var1>
<var2>W</var2>
<var3>E</var3>
</tbl>
</DocumentElement>
]]>
</ns1:xmlstring>
</ns1:functionHere>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
How can I prevent this to happen? I hope someone can help us with this.
Related
I have an associative array:
$params = [
'trid' => null,
'merchantCode' => null,
'paymentMethod' => null,
'returnUrl' => site_url(null),
'notificationUrl' => site_url(null),
'language' => 'null',
'currency' => 'null',
'isTestMode' => false,
'productsXml' => null,
'needInvoice' => true,
(Nulls hold actual values in reality)
When I check __getLastRequest I completly lose the keys in the generated XML.
SoapClient,
$soap = new SoapClient(null, $options);
$soap->__soapCall('Request', $params);
$request = $soap->__getLastRequest();
Please note that I have a NON WSDL connection to the endpoint.
The generated XML will have a field value of <param[keyNum] xsi:type="xsd:typeOfVariable"> instead of having the actual key value from the associative array, <trid> for example.
<SOAP-ENV:Body><ns1:Request><param0 xsi:type="xsd:string">null</param0><param1 xsi:type="xsd:string">null</param1></Request>
Contrary to what the PHP manual says, it seems arguments is never interpreted as an associative array.
If we try this simple test:
<?php
$options = ['location'=>'http://localhost/unknown', 'uri'=>'test', 'trace'=>true];
$soap = new SoapClient(null, $options);
try
{
$soap->__soapCall('Request', ['foo'=>1, 'bar'=>2]);
}
catch(SoapFault $e)
{
header('Content-type: text/xml');
echo $soap->__getLastRequest();
}
?>
we get:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:Request>
<param0 xsi:type="xsd:int">1</param0>
<param1 xsi:type="xsd:int">2</param1>
</ns1:Request>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
We see that the parameter names are ignored.
Now if we try what the other answer suggests (wrap the array in another array):
<?php
$options = ['location'=>'http://localhost/unknown', 'uri'=>'test', 'trace'=>true];
$soap = new SoapClient(null, $options);
try
{
$soap->__soapCall('Request', [['foo'=>1, 'bar'=>2]]);
}
catch(SoapFault $e)
{
header('Content-type: text/xml');
echo $soap->__getLastRequest();
}
?>
we get:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:Request>
<param0 xsi:type="ns2:Map">
<item>
<key xsi:type="xsd:string">foo</key>
<value xsi:type="xsd:int">1</value>
</item>
<item>
<key xsi:type="xsd:string">bar</key>
<value xsi:type="xsd:int">2</value>
</item>
</param0>
</ns1:Request>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
We see that there is a single parameter whose type is Map. That's not what we want.
The solution is to use the SoapParam class:
<?php
$options = ['location'=>'http://localhost/unknown', 'uri'=>'test', 'trace'=>true];
$soap = new SoapClient(null, $options);
try
{
$soap->__soapCall('Request', [new SoapParam(1, 'foo'), new SoapParam(2, 'bar')]);
}
catch(SoapFault $e)
{
header('Content-type: text/xml');
echo $soap->__getLastRequest();
}
?>
Now we get what we wanted:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:Request>
<foo xsi:type="xsd:int">1</foo>
<bar xsi:type="xsd:int">2</bar>
</ns1:Request>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Note that you can easily convert an associative array to SOAP parameters like this:
function getSoapParams($params)
{
$a = [];
foreach($params as $name=>$value)
$a[] = new SoapParam($value, $name);
return $a;
}
According to notes in the documentation
If you want to call __soapCall, you must wrap the arguments in another array as follows:
$params = array('username'=>'name', 'password'=>'secret');
<?php
$client->__soapCall('login', array($params));
?>
The following line:
$soap->__soapCall('Request', $params);
Should be:
$soap->__soapCall('Request', [$params]);
How do i create this specific xml output by SOAP using SoapHeader and __setSoapHeaders? I can't do the same XML like i want. i don't want this ns1 and ns2 in envelope tag, and in header i need this Action SOAP-ENV:mustUnderstand="1" ...
This is my code:
try{
$client = new SoapClient('https://thesite.com.br/wcf/SvcContratos.svc?wsdl', array('trace' => 1,'use' => SOAP_LITERAL));
$usuario='user_1';
$senha='1234';
$tipo='1';
$header = new SoapHeader("http://schemas.microsoft.com/ws/2005/05/addressing/none","Action", "http://tempuri.org/ISvcContratos/GerarToken");
$client->__setSoapHeaders($header);
$params = new SoapVar("<objLogin xmlns:d4p1='http://schemas.datacontract.org/2004/07/EPFWeb.Repository.Default.WCF' xmlns:i='http://www.w3.org/2001/XMLSchema-instance'><d4p1:DsSenha>".$senha."</d4p1:DsSenha><d4p1:DsUsuario>".$usuario."</d4p1:DsUsuario><d4p1:IdTipoConsulta>".$tipo."</d4p1:IdTipoConsulta></objLogin>", XSD_ANYXML);
$data = $client->GerarToken($params);
echo $client->__getLastRequest();
}catch(SoapFault $fault){
echo $client->__getLastRequest()."<br>".$fault->getMessage();
}
With this php code i had this wrong XML:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/" xmlns:ns2="http://schemas.microsoft.com/ws/2005/05/addressing/none">
<SOAP-ENV:Header>
<ns2:Action>http://tempuri.org/ISvcContratos/GerarToken</ns2:Action>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<GerarToken>
<objLogin xmlns:d4p1='http://schemas.datacontract.org/2004/07/EPFWeb.Repository.Default.WCF' xmlns:i='http://www.w3.org/2001/XMLSchema-instance'>
<d4p1:DsSenha>1234</d4p1:DsSenha>
<d4p1:DsUsuario>user_1</d4p1:DsUsuario>
<d4p1:IdTipoConsulta>1</d4p1:IdTipoConsulta>
</objLogin>
</GerarToken>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I need to send this XML by soap:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/ISvcContratos/GerarToken</Action>
</s:Header>
<s:Body>
<GerarToken xmlns="http://tempuri.org/">
<objLogin xmlns:d4p1="http://schemas.datacontract.org/2004/07/EPFWeb.Repository.Default.WCF" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<d4p1:DsSenha>1234</d4p1:DsSenha>
<d4p1:DsUsuario>USER_1</d4p1:DsUsuario>
<d4p1:IdTipoConsulta>1</d4p1:IdTipoConsulta>
</objLogin>
</GerarToken>
</s:Body>
</s:Envelope>
well, finally I got an affirmative answer from the server, which opens the doors for me now to try to consume the wsdl follows below the code that I used to solve the problem:
try{
$client = new SoapClient('https://thesite.com.br/wcf/SvcContratos.svc?wsdl', array('trace' => 1,'use' => SOAP_LITERAL, 'style' => SOAP_DOCUMENT,));
$usuario='user_1';
$senha='1234';
$params = new SoapVar("<GerarToken xmlns='http://tempuri.org/'><objLogin xmlns:d4p1='http://schemas.datacontract.org/2004/07/EPFWeb.Repository.Default.WCF' xmlns:i='http://www.w3.org/2001/XMLSchema-instance'><d4p1:DsUsuario>".$usuario."</d4p1:DsUsuario><d4p1:DsSenha>".$senha."</d4p1:DsSenha><d4p1:IdTipoConsulta>Data</d4p1:IdTipoConsulta></objLogin></GerarToken>", XSD_ANYXML);
$data = $client->GerarToken($params);
$xml = json_decode(json_encode($data),true);
print_r($xml);
echo $client->__getLastRequest();
}catch(SoapFault $fault){
echo $client->__getLastRequest()."<br>".$fault->getMessage();
}
In PHP I need to create a soap-xml request like
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Header xmlns:NS1="urn:UCoSoapDispatcherBase" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<NS1:TAuthenticationHeader xsi:type="NS1:TAuthenticationHeader">
<UserName xsi:type="xsd:string">user</UserName>
<Password xsi:type="xsd:string">pass</Password>
</NS1:TAuthenticationHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<NS2:ExecuteRequest xmlns:NS2="urn:UCoSoapDispatcherCustomLink-ICustomLinkSoap">
<ARequest xsi:type="xsd:string">
<?xml version="1.0" encoding="windows-1252"?> <EoCustomLinkRequestDateTime Type="TEoCustomLinkRequestDateTime"></EoCustomLinkRequestDateTime>
</ARequest>
</NS2:ExecuteRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
But the problem is to get param in the header (like xmlns:NS1...) and body (like xmlns:NS2...) tags
With my script I get NS1 and NS2 swapped in the first tag after header and body. results in <NS1:TAuthenticationHeader> .... and . </NS2:ExecuteRequest>
My php script:
<?php
$wsdl_url = 'http://xxx.xxx.xxx.xxx:yyyy/wsdl/ICustomLinkSoap';
$location = 'http://xxx.xxx.xxx.xxx:yyyy/soap/ICustomLinkSoap';
$action = 'ExecuteRequest';
$version = SOAP_1_1;
$one_way = 0;
$soapClient = new SoapClient($wsdl_url, array(
'cache_wsdl' => WSDL_CACHE_NONE,
'trace' => true,
'encoding' => 'ISO-8859-1',
'exceptions' => true,
));
$auth = (object)array(
'UserName'=>'xxxx',
'Password'=>'yyyy'
);
$header = new SoapHeader($wsdl_url,'TAuthenticationHeader',$auth,false);
$soapClient->__setSoapHeaders($header);
$request1 = '
<ARequest>
<?xml version="1.0" encoding="windows-1252"?>
<EoCustomLinkRequestDateTime Type="TEoCustomLinkRequestDateTime" xsi:noNamespaceSchemaLocation="GdxEoStructures.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
</EoCustomLinkRequestDateTime></ARequest>
';
$xmlVar = new SoapVar($request1, XSD_ANYXML);
$result = $soapClient->__SoapCall(
'ExecuteRequest',
array($xmlVar)
);
// show result in xml-file
$f = fopen("./soap-request2.xml", "w");
xx = serialize($soapClient->__getLastRequest());
fwrite($f, $xx);
?>
Result:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn:UCoSoapDispatcherCustomLink-ICustomLinkSoap"
xmlns:ns2="http://xxx.xxx.xxx.xxx:yyy/wsdl/ICustomLinkSoap"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Header>
<ns2:TAuthenticationHeader>
<UserName>xxxx</UserName>
<Password>yyyy</Password>
</ns2:TAuthenticationHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:ExecuteRequest>
<ARequest>
<?xml version="1.0" encoding="windows-1252"?>
<EoCustomLinkRequestDateTime Type="TEoCustomLinkRequestDateTime" xsi:noNamespaceSchemaLocation="GdxEoStructures.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
</EoCustomLinkRequestDateTime>
</ARequest>
</ns1:ExecuteRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Please help to how to do so?
Eric
But the problem is to get param in the header (like xmlns:NS1...) and
body (like xmlns:NS2...) tags With my script I get NS1 and NS2 swapped
in the first tag after header and body. results in
.... and .
It's not a problem, because swapped not only namespaces of elements but also its definitions at the head of SOAP-ENV:Envelope
Your first xml
xmlns:NS1="urn:UCoSoapDispatcherBase"
xmlns:NS2="urn:UCoSoapDispatcherCustomLink-ICustomLinkSoap"
Compare with generated by php
xmlns:ns1="urn:UCoSoapDispatcherCustomLink-ICustomLinkSoap"
xmlns:ns2="http://xxx.xxx.xxx.xxx:yyy/wsdl/ICustomLinkSoap"
I am trying to populate a request using nusoap and php 5.3. Everything I have tried has left me with an empty request. Where am I going wrong?
This is what i'm trying to create…
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance">
<soap:Header>
<CardSoapHeader xmlns="https://service.pct.com/">
<Username>username</Username>
<Password>password</Password>
<Account>account</Account>
</CardSoapHeader>
</soap:Header>
<soap:Body>
<AddressLookup xmlns="https://service.pct.com/">
<request>
<CompanyReferenceGuid>00000000-0000-0000-0000</CompanyReferenceGuid>
<AdminUserIdentifier>00000000-0000-0000-0000</AdminUserIdentifier>
<MirrorRequest>false</MirrorRequest>
<Surname>surname</Surname>
<Postcode>postcode</Postcode>
<HouseName>1</HouseName>
<AuthenticateCardApplicants>false</AuthenticateCardApplicants>
</request>
</AddressLookup>
</soap:Body>
</soap:Envelope>
This is my php…
<?php
require_once('./soap/lib/nusoap.php');
$client = new nusoap_client('https://uat.service.efirstcard.co.uk/v3_1/SignupService.asmx?wsdl', 'wsdl');
$requestArray[] = array(
/*
'CardSoapHeader' => array('Username' => 'username',
'Password' => 'password',
'Account' => 'account'),
*/
'CompanyReferenceGuid' => '00000000-0000-0000-0000',
'AdminUserIdentifier' => '00000000-0000-0000-0000',
'MirrorRequest' =>'false',
'Surname' =>'surname',
'Postcode' =>'postcode',
'HouseName' =>'1',
'AuthenticateCardApplicants' =>'false');
// Doc/lit parameters get wrapped
$result = $client->call('AddressLookup', array('request' => array($requestArray)));
echo '<h2>Request</h2><pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
echo '<h2>Response</h2><pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';
echo '<h2>Debug</h2><pre>' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '</pre>';
?>
And this is what it generates…
<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns9681="http://tempuri.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<AddressLookup xmlns="https://service.pct.com/">
<request></request>
</AddressLookup>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I'm trying to login to an API using built-in soap functions of PHP. I got a result like this.
[LoginResult]=> false,
[ErrorMsg] => Login failed with the reason : The security object is invalid
This is what required by the API provider.
<?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>
<Login xmlns="http://tempuri.org/Example/Service1">
<objSecurity>
<WebProviderLoginId>test</WebProviderLoginId>
<WebProviderPassword>test</WebProviderPassword>
<IsAgent>false</IsAgent>
</objSecurity>
<OutPut />
<ErrorMsg />
</Login>
</soap:Body>
</soap:Envelope>
&, here is what I was able to produce using functions.
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/Example/Service1">
<SOAP-ENV:Body>
<ns1:Login>
<objSecurity>
<WebProviderLoginId>test</WebProviderLoginId>
<WebProviderPassword>test</WebProviderPassword>
<IsAgent>false</IsAgent>
</objSecurity>
<OutPut/>
<ErrorMsg/>
</ns1:Login>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Here is the code I used to send the request.
<?php
class objSecurity {
function objSecurity($s, $i, $f) {
$this->WebProviderLoginId = $s;
$this->WebProviderPassword = $i;
$this->IsAgent = $f;
}
}
class nextObject {
function nextObject($objSecurity) {
$this->objSecurity=$pobjSecurity;
$this->OutPut=NULL;
$this->ErrorMsg=NULL;
}
}
$url = 'http://example.com/sampleapi/test.asmx?WSDL';
$client = new SoapClient($url, array("soap_version" => SOAP_1_1,"trace" => 1));
$struct = new objSecurity('test', 'test', false);
$data = new nextObject($struct);
$soapstruct2 = new SoapVar($data, SOAP_ENC_OBJECT);
print_r(
$client->__soapCall(
"Login",
array(new SoapParam($soapstruct2, "inputStruct"))
)
);
echo $client->__getLastRequest();
?>
These are the differences I found.
In my request xmlns:xsi is missing.
Requirement starts with <soap:Envelope, But my request starts with <SOAP-ENV:Envelope.
There is an extra xmlns:ns1 in my request.
& The function name tag starts with ns1:.
Please help me to make my request into the required format.
I don't know much about the SOAP and I'm using PHP version 5.3.13 with CakePHP 2.3.0. Sorry, for my bad English.
Here is the solution. :)
<?php
$url = 'http://example.com/sampleapi/test.asmx?WSDL';
$client = new SoapClient($url, array("soap_version" => SOAP_1_1,"trace" => 1));
$user_param = array (
'WebProviderLoginId' => "test",
'WebProviderPassword' => "test",
'IsAgent' => false
);
$service_param = array (
'objSecurity' => $user_param,
"OutPut" => NULL,
"ErrorMsg" => NULL
);
print_r(
$client->__soapCall(
"Login",
array($service_param)
)
);
echo $client->__getLastRequest();
?>
& the request was:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/Example/Service1">
<SOAP-ENV:Body>
<ns1:Login>
<ns1:objSecurity>
<ns1:WebProviderLoginId>test</ns1:WebProviderLoginId>
<ns1:WebProviderPassword>test</ns1:WebProviderPassword>
<ns1:IsAgent>false</ns1:IsAgent>
</ns1:objSecurity>
</ns1:Login>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Thanks to this link.
PHP SOAP Request not right