Formatting namespace in soap header using PHP - php

I need to construct an XML SOAP request header using PHP where the output looks like this:
<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:Header>
<AuthTokenHeader xmlns="SPP.net/ContractData">
<Token>B1912A8BA7AB6E56D688244D7B</Token>
</AuthTokenHeader>
</soap:Header>
....but my PHP is producing this instead:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="SPP.net/ContractData">
<SOAP-ENV:Header>
<ns1:AuthTokenHeader>
<Token>373161D1C28</Token>
</ns1:AuthTokenHeader>
</SOAP-ENV:Header>
Here is my PHP code:
// define namespace
$NameSpace = 'SPP.net/ContractData';
// build AuthTokenHeader vars
$authTokenVar[] = new SoapVar($TOKEN, XSD_STRING, null, null, 'Token');
// wrap in AuthTokenHeader tags
$header = new SoapVar($authTokenVar, SOAP_ENC_OBJECT, null, null, 'AuthTokenHeader');
// build soap header
$soapHeader = new SoapHeader($NameSpace, 'AuthTokenHeader', $header , false);
// instanciate soap client
$wsdlUrl= "https://gmwstest.sppinc.net/VPP/ContractExchange.asmx?wsdl";
$client = new SoapClient($wsdlUrl,
array(
"trace" => 1,
"exceptions" => 0,
"cache_wsdl" => 0));
// set soap headers
$client->__setSoapHeaders($soapHeader);
Here is the entire XML soap request I need to build:
<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:Header>
<AuthTokenHeader xmlns="SPP.net/ContractData">
<Token>BEB40F7FD43168017ACF3772A91F2B7C2B37A722F6421598D0B61CCD3DBF8928CA18B25970AB6D43FD31A761F15D84A52C9FC315BE9F708F30EE4F08DAB4C74F94894A7D3242102831FB8303684F7FE492A2249CB35FB50030C905DD91F771103C5A1D486CCEA9AAB0D42AC37252B2E350B4E3F24CEE8D0B8CFCE04F1DD7D1B4D7C2A4F1912A8BA7AB6E56D688244D7B</Token> <!--GET TOKEN FROM LOGONRESULT SESSION VARIABLE-->
</AuthTokenHeader>
</soap:Header>
<soap:Body>
<SendContractData xmlns="SPP.net/ContractData">
<contract>
<ContractID>VPP00253221</ContractID> <!--GET ContractID FROM CONTRACT RESPONSE SESSION VARIABLE-->
<AccountNumber/>
<Status>Pending</Status>
<Company>VPP</Company>
<ContractPrefix/>
<DealerCode>10456</DealerCode>
<FirstName>FirstName</FirstName>
<Mi/>
<LastName>Lastname</LastName>
<PhoneNumber>(312)980-6000</PhoneNumber>
<Address1>303 Anytown Lane</Address1>
<Address2>Unit A</Address2>
<City>Yourtown</City>
<StateProvinceAbbr xsi:type="StateEnum">IL</StateProvinceAbbr>
<ZipCode>60601</ZipCode>
<Country>USA</Country>
<OriginatingDepartment>Other</OriginatingDepartment>
<Language>English</Language>
<VIN>1HGCM56705AJMD227</VIN>
<PurchasePrice>2000.00</PurchasePrice>
<SalesTax>0.00</SalesTax>
<DownPayment>200.00</DownPayment>
<AmountFinanced>1800.00</AmountFinanced>
<PolicyType>ServiceContract</PolicyType>
<InServiceDate>2010-03-12T00:00:00</InServiceDate>
<FirstPaymentDate xsi:nil="true"/>
<DealerCost>500</DealerCost>
<ContractHoldersInitialsCoordinates xsi:nil="true"/>
<ContractHoldersInitialsDateCoordinates xsi:nil="true"/>
<ContractHoldersSignatureCoordinates xsi:nil="true"/>
<SignatureDateCoordinates xsi:nil="true"/>
<SellersSignatureCoordinates xsi:nil="true"/>
<PurchaseDate>2014-06-23T14:24:46</PurchaseDate>
<BeginMileage>43650</BeginMileage>
<TermMonths>84</TermMonths>
<TermMileage>100000</TermMileage>
<NumberOfPayments>12</NumberOfPayments>
<CallBackURL>http://NewWarrantyVehicle_Example/Success.php</CallBackURL>
</contract>
</SendContractData>
</soap:Body>
</soap:Envelope>

The two XML snippets you presented are logically the same. Both reference the XML namespace for the AuthTokenHeader element differently, but in terms of a correctly working XML parser they express the same.
You cannot change the way PHP creates the XML of a Soap request. If the created request does not work with the server you have to use, please be more specific what problems you encounter.

Related

PHP SOAP:How to get param inside xml header and body tag

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"

Print specific element consuming SOAP with XML

I'm using the integrated SOAP client in PHP 5.3 and I've tested with this web service: http://www.webservicex.net/globalweather.asmx
I'm calling this method 'GetWeather' and the XML request looks like this:
<?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>
<GetWeather xmlns="http://www.webserviceX.NET">
<CityName>string</CityName>
<CountryName>string</CountryName>
</GetWeather>
</soap:Body>
</soap:Envelope>
and response XML is like this:
<?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>
<GetWeatherResponse xmlns="http://www.webserviceX.NET">
<GetWeatherResult>string</GetWeatherResult>
</GetWeatherResponse>
</soap:Body>
</soap:Envelope>
So far I'm getting successfully the array with this code:
<?php
$client = new SoapClient('http://www.webservicex.net/globalweather.asmx?WSDL');
$result = $client->GetWeather(array('CityName' => 'Barcelona', 'CountryName' => 'Spain'));
print_r ($result);
How can I print specific element, let's say the value of the CityName?
So when I want to print the city like this:
echo '<div> ' . $city . '</div>';
How do I get the value of the CityName?

Difference between two soap requests

My SOAP Request
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://ws.dgpys.deloitte.com" xmlns:ns2="ws.apache.org/namespaces/axis2">
<env:Header>
<ns2:ServiceGroupId>
<BOGUS>urn:uuid:7C2F61BDE7CB9D9C6D1424938568724</BOGUS>
</ns2:ServiceGroupId>
</env:Header>
<env:Body>
<ns1:getGunlukParametreRapor>
<date>2015-02-22T00:00Z</date>
</ns1:getGunlukParametreRapor>
</env:Body>
</env:Envelope>
Expected SOAP Request
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://ws.dgpys.deloitte.com">
<soap:Header>
<axis2:ServiceGroupId xmlns:axis2="http://ws.apache.org/namespaces/axis2">urn:uuid:479731898147E116AD1424691518968</axis2:ServiceGroupId>
</soap:Header>
<soap:Body>
<ws:getGunlukParametreRapor>
<date>2015-02-22T00:00Z</date>
</ws:getGunlukParametreRapor>
</soap:Body>
</soap:Envelope>
Tried with following codes:
$options = array(
'trace' => 1,
'exceptions' => 1,
'soap_version' => SOAP_1_2
);
$client = new SoapClient("http://dgpysws.pmum.gov.tr/dgpys/services/EVDServis.wsdl", $options);
$p1 = new stdCLass();
$p1->loginMessage = new stdCLass();
$p1->loginMessage->UserName = new stdCLass();
$p1->loginMessage->UserName->v = "Username";
$p1->loginMessage->Password = new stdCLass();
$p1->loginMessage->Password->v = "Passwor";
$client->login($p1);
$headers[] = new SoapHeader('http//ws.apache.org/namespaces/axis2', 'ServiceGroupId', "UNIQUEID", false);
$client->__setSoapHeaders($headers);
$result = $client->getGunlukParametreRapor(array('date' => '2015-02-22T00:00Z'));
Question is:
These SOAP requests are same?
I'm using SOAP_1_2 and it should be like Expected SOAP Request but my request doesnt looks like to expected format. Missing where?
How can i get the output like as expected?
Note: dgpysws.pmum.gov.tr wsdl address is private area.
They are not the same. To get rid of the BOGUS node you need to use this:
$strHeaderComponent_Session = "<SessionHeader><ServiceGroupId>$theVarWithTheIDGoesHere</ServiceGroupId></SessionHeader>";
$objVar_Session_Inside = new SoapVar($strHeaderComponent_Session, XSD_ANYXML,
null, null, null);
$objHeader_Session_Outside = new SoapHeader('http//ws.apache.org/namespaces/axis2',
'SessionHeader', $objVar_Session_Inside);
// More than one header can be provided in this array.
$client->__setSoapHeaders(array($objHeader_Session_Outside));
try the following
$ns = 'http//ws.apache.org/namespaces/axis2'; //Namespace of the WS.
//Body of the Soap Header.
$headerbody = array('ServiceGroupId' => $UNIQUEID_Token);
//Create Soap Header.
$header = new SOAPHeader($ns, 'axis2', $headerbody);
//set the Headers of Soap Client.
$soap_client->__setSoapHeaders($header);
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://ws.dgpys.deloitte.com" xmlns:ns2="ws.apache.org/namespaces/axis2">
<env:Header>
<ns2:ServiceGroupId>
urn:uuid:7C2F61BDE7CB9D9C6D1424938568724
</ns2:ServiceGroupId>
</env:Header>
<env:Body>
<ns1:getGunlukParametreRapor>
<date>2015-02-22T00:00Z</date>
</ns1:getGunlukParametreRapor>
</env:Body>
</env:Envelope>
And
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://ws.dgpys.deloitte.com">
<soap:Header>
<axis2:ServiceGroupId xmlns:axis2="http://ws.apache.org/namespaces/axis2">urn:uuid:479731898147E116AD1424691518968</axis2:ServiceGroupId>
</soap:Header>
<soap:Body>
<ws:getGunlukParametreRapor>
<date>2015-02-22T00:00Z</date>
</ws:getGunlukParametreRapor>
</soap:Body>
</soap:Envelope>
Are the same.
env=soap, ns2=ws and ns2=axis2. You can have any prefix to refer to these namespaces as you like. Once you assign the prefix you just refer to it using that in the other places. Only diff was the bogus tag tin first request. Just remove that.

PHP sending SOAP request with SOAP client

It's my first time with SOAP, I already read all manuals and still stacked with the following example:
<?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:Header>
<AuthenticationInfo xmlns="https://blabla.com/ws/Quoting">
<strUserName>[username]</strUserName>
<strPassword>[password]</strPassword>
</AuthenticationInfo>
</soap:Header>
<soap:Body>
<GetQuotes xmlns="https://blabla.com/ws/Quoting">
<CallerClientID>0</CallerClientID>
<quoteRequest>
<CapacityCode>2</CapacityCode>
<BabiesCount>0</BabiesCount>
<QuotingOptions>0</QuotingOptions>
</quoteRequest>
<clientIDs>
<int>20295</int>
</clientIDs>
<withUrlParam>false</withUrlParam>
</GetQuotes>
</soap:Body>
</soap:Envelope>
I do not understand how to start the soapclient with authorization, please help.
You need to use SoapHeader. Below is the example.
$ns = 'https://blabla.com/ws/Quoting'; //Namespace of the WS.
//Body of the Soap Header.
$headerbody = array('strUserName' => $someUser,
'strPassword' => $somePass);
//Create Soap Header.
$header = new SOAPHeader($ns, 'AuthenticationInfo', $headerbody);
//set the Headers of Soap Client.
$soap_client->__setSoapHeaders($header);

Parsing XML request

I'm very very new to being on the Server side of things. I need to set up a simple server.php to receive xml requests.
I'm not even sure how to start with this. I am used to the normal Post/Get variables from forms.
Here's an example of what I'm listening for, and needing to respond to:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV: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:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<authenticate xmlns="http://someplace.someplace.com/">
<strUserName xsi:type="xsd:string">username</strUserName>
<strPassword xsi:type="xsd:string">password</strPassword>
</authenticate>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Obviously there's a username/password I can see inside.
Validating the user/pass is the easy part, but how do I parse that out?
You can also use DOM element to access your desired values:
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV: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:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<authenticate xmlns="http://someplace.someplace.com/">
<strUserName xsi:type="xsd:string">username</strUserName>
<strPassword xsi:type="xsd:string">password</strPassword>
</authenticate>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
$dom = new DOMDocument();
$dom->loadXML( $xml );
$username = $dom->getElementsByTagName('strUserName')->item(0)->nodeValue;
$password = $dom->getElementsByTagName('strPassword')->item(0)->nodeValue;
Give it a try with SimpleXML, you have a few examples here:
SimpleXML examples
You should probably use existing API when parsing a SOAP request. This will not only automatically get rid of your parsing problems but also generate correct SOAP output.
Example:
$request = '<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV: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:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<authenticate xmlns="http://someplace.someplace.com/">
<strUserName xsi:type="xsd:string">foo</strUserName>
<strPassword xsi:type="xsd:string">bar</strPassword>
</authenticate>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
$s = new SoapServer(NULL, array('uri' => 'http://someplace.someplace.com/'));
$s->setClass("Auth");
$s->handle($request);
class Auth
{
public function authenticate($strUserName, $strPassword)
{
return "U: $strUserName; P: $strPassword";
}
}
Note: If you do not pass an argument to handle() it will use POST data.

Categories