Pass raw xml to SOAP in PHP - php

If I have a raw XML message that I need to pass in PHP, is there an easy way to pass it?
Something like this:
$xml = '
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Header>
...
</soap:Header>
<soap:Body>
...
<soap:Fault>
...
</soap:Fault>
</soap:Body>
</soap:Envelope>';
$url = 'http://www.myurl.com';
passXmlToSoap($xml,$url);
I am not trying to master using SOAP and I only need to use it to do a very simple thing so I am hoping that I can use raw XML and do it as simply as possible even though that might not be "the right way" to do it.

check this answer:
How to parse SOAP XML?
there should be libraries for parsing XML, but that answer gives you an straightforward way to do it. Good Luck
it works:
$xml = '<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Header>
<Name>Yo</Name>
</soap:Header>
<soap:Body>
<payment>
<uniqueReference>ESDEUR11039872</uniqueReference>
<epacsReference>74348dc0-cbf0-df11-b725-001ec9e61285</epacsReference>
<postingDate>2010-11-15T15:19:45</postingDate>
<bankCurrency>EUR</bankCurrency>
<bankAmount>1.00</bankAmount>
<appliedCurrency>EUR</appliedCurrency>
<appliedAmount>1.00</appliedAmount>
<countryCode>ES</countryCode>
<bankInformation>Sean Wood</bankInformation>
<merchantReference>ESDEUR11039872</merchantReference>
</payment>
</soap:Body>
</soap:Envelope>';
$xml = simplexml_load_string($xml);
print_r( $xml) ;
$xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
foreach ($xml->xpath('//payment') as $item)
{
print_r($item);
}

In any case you should never have to parse XML response nor pass XML request to consume SOAP Web Service.
First if you use the native php SoapClient class you send an object or an array. Then you receive stdClass objects
Second, you should use a WSDL to php generator that generates classes mathing the parameters that has to be sent. It also generated the classes that match the response object. Finally, it generated the classes to send the request. So you can send the request and receive the response very easily without any doubt and without having to deal with XML.
Try PackageGenerator project.

Related

How to make proper SOAP request using PHP SoapClient when we see an example

I want to receive data using method GetCruise
How to do that in php using SoapClient, of course i know all URLs and I've got PartnerName, Password and AgencyCode
especially i need to know how to construct proper header of envelope using SoapClient::__setSoapHeaders
GetCruise
Call:
Proxy.Availability.GetCruise(“FO11060119”);
Parameters:
CruiseCode - the cruise code to be returned
Returns:
a fully described cruise (including itinerary and segments of an itinerary).
Example of soap envelope:
(headers must contain agency data - name paswword etc. i've got it)
SOAPAction: "http://schemas.costacrociere.com/WebAffiliation/GetCruise"
<?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>
<Agency xmlns="http://schemas.costacrociere.com/WebAffiliation">
<Code>1111</Code>
<Culture />
</Agency>
<Partner xmlns="http://schemas.costacrociere.com/WebAffiliation">
<Name>AAAA</Name>
<Password>XXXX</Password>
</Partner></soap:Header>
<soap:Body>
<GetCruise xmlns="http://schemas.costacrociere.com/WebAffiliation">
<CruiseCode>FO11060119</CruiseCode>
</GetCruise>
</soap:Body>
</soap:Envelope>

SOAP Envelope Element is not declared

I have an issue with a SOAP request I'm sending to an external ASP Web Service. I have used both SoapUI and PHP's SoapClient class, and both times the same issue occurs - an error that tells me The 'http://www.w3.org/2003/05/soap-envelope:Envelope' element is not declared.
My Request to 'GetStudentEntitlement'
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:adm="http://dest.gov.au/Heims/Admin/" xmlns:heim="http://dest.gov.au/Heims/">
<soap:Header/>
<soap:Body><adm:GetStudentEntitlement>
<heim:entitlementRequest>
<heim:RequestControlTable>
<heim:RequestId>CDD1E704-1298-4D42-AAD9-0031BB90329F</heim:RequestId>
<heim:ClientOrganisationCode>7591</heim:ClientOrganisationCode>
<heim:RequestLocalDateTime>2015-08-10T00:00:00</heim:RequestLocalDateTime>
</heim:RequestControlTable>
<heim:GetEntitlementIn>
<heim:RecordId>CDD1E704-1298-4D42-AAD9-0031BB90329F</heim:RecordId>
<heim:Chessn>1344</heim:Chessn>
<heim:FamilyName>Bassett</heim:FamilyName>
<heim:BirthDate>1988-05-21</heim:BirthDate>
</heim:GetEntitlementIn>
</heim:entitlementRequest>
</adm:GetStudentEntitlement>
</soap:Body>
</soap:Envelope>
The response:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<soap:Code>
<soap:Value>soap:Sender</soap:Value>
</soap:Code>
<soap:Reason>
<soap:Text xml:lang="en">Heims.WebServices.Extensions.Exceptions.XmlSchemaValidationException: Schema validation errors
at Heims.WebServices.Extensions.SoapFilterExtension.ValidateXmlMessage(SoapMessage message, WebMethodSettings methodSettings) in c:\Userdata\HEIMS.NET\Source\Development\WebService\Heims.WebService.Common\Extensions\SoapFilterExtension.cs:line 408
at Heims.WebServices.Extensions.SoapFilterExtension.ProcessMessageBeforeDeserialise(SoapMessage message) in c:\Userdata\HEIMS.NET\Source\Development\WebService\Heims.WebService.Common\Extensions\SoapFilterExtension.cs:line 200
at Heims.WebServices.Extensions.SoapFilterExtension.ProcessMessage(SoapMessage message) in c:\Userdata\HEIMS.NET\Source\Development\WebService\Heims.WebService.Common\Extensions\SoapFilterExtension.cs:line 173
at System.Web.Services.Protocols.SoapMessage.RunExtensions(SoapExtension[] extensions, Boolean throwOnException)
at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()
at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()</soap:Text>
</soap:Reason>
<detail>
<ValidationError>
<RecordId/>
<Element>Envelope</Element>
<Line>1</Line>
<Column>2</Column>
<Description>The 'http://www.w3.org/2003/05/soap-envelope:Envelope' element is not declared.</Description>
</ValidationError>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
I have tried adding and removing the trailing / on the :soap declaration, as well as trying both the 1.1 and 1.2 SOAP versions offered by this web service.
This endpoint request to 'Ping' works correctly:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:adm="http://dest.gov.au/Heims/Admin/">
<soap:Header/>
<soap:Body>
<adm:Ping/>
</soap:Body>
</soap:Envelope>
The result is returned as expected:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<PingResponse xmlns="http://dest.gov.au/Heims/Admin/">
<PingResult>Heims web services pinged. DateTime = 2015-08-10 11:11:00:05</PingResult>
</PingResponse>
</soap:Body>
</soap:Envelope>
So why would the code for one request (the ping) work perfectly, while the other request (GetStudentEntitlement) fails? Both have the soap:Envelope declaration, but the Ping request works fine.
I have also tried using xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" in the soap:Envelope element, but the error remained.
Is it possible that this is a server-side issue from the Web Service itself? Or is something simply going wrong in my code?
Answering my own question.
I contact the Government IT Assistance directly, and had them send me a code example. They were using a highly unusual and modified form of <soap wrapper, forcing me to manually generate the XML using SimpleXMLElement and submit to the Web Service using a wrapped SoapVar with the XSD_ANYXML type.
Did you get any solution to this...
I have encountered same problem today while converting UTL_DBWS utility (oracle plsql) to APEX utilities to make calls to HEIMS web service.
Ping worked but GetStudentEntitlements and AllocateStudentChessn both are failing with same envelop error.
Regards
RC

PHP SOAP Why are parameters not being sent?

I need to send a SOAP request to a .NET Web Services (*.asmx). I am creating a WSDL SoapClient object and I need to make a __soapCall sending 2 parameters: LoginName and Password. The XML should be something like the exemple to work, but the XML created has the parameters all confused.
This is the code:
$client = new SoapClient("https://server/service.asmx?WSDL",array("trace"=>1,'soap_version' => SOAP_1_2));
$client->__setCookie('ticket',$ticket);
$param= array('LoginName'=>'name','Password'=> base64_encode('123456'));
$client->__soapCall('AddPlayer', $param);
echo "REQUEST:\n" . htmlentities($sweepStakesClient->__getLastRequest()) . "\n";
Also tried:
$param = array(new SoapParam('name','LoginName'),new SoapParam(base64_encode('123456'),'Password'));
Echo returns:
REQUEST: <?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://server.com/Service">
<env:Body>
<ns1:AddPlayer/>
<Password>MTIyMzQ1NTY=</Password>
</env:Body>
</env:Envelope>
I need it to be something like:
<?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>
<AddPlayer xmlns="http://server.com/Service">
<request>
<LoginName>name</LoginName>
<Password>MTIyMzQ1NTY=</Password>
</request>
</AddPlayer>
</soap12:Body>
</soap12:Envelope>
Please pay attention to the documentation provided on php.net regarding the method you use here, SoapClient::__soapCall():
This is a low level API function that is used to make a SOAP call. Usually, in WSDL mode, SOAP functions can be called as methods of the SoapClient object. This method is useful in non-WSDL mode when soapaction is unknown, uri differs from the default or when sending and/or receiving SOAP Headers.
You're in WSDL mode, so you don't need to use it at all. Instead call the method directly:
$client->AddPlayer('name', 'MTIyMzQ1NTY');
When you debug you should see that it matches up with the method name and the two parameters. In case not, fall-back to SoapClient::__call() and use the array with the named parameters again as second parameter. But it's much more comfortable to do it the WSDL style with named methods.

soap api with betfair

It's my first time using the SOAP API by BetFair I have created one XML file and one file that will call that file. I am not understanding how can I call this and get an output. I have created the XML file below:
<?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://www.betfair.com/publicapi/v3/BFGlobalService/">
<request>
<locationId xmlns="">0</locationId>
<username xmlns="">usrname</username>
<password xmlns="">password</password>
<productId xmlns="">18</productId>
<vendorSoftwareId xmlns="">0</vendorSoftwareId>
</request>
</login>
</soap:Body>
</soap:Envelope>
Now to call this file I have also created one php file to do this.
BetFair has given this link for the login api: https://api.betfair.com/global/v3/BFGlobalService.wsdl
<?php
$get_data = file_get_contents("http://pixelonsell.com/dev2/betfair/login.xml");
$b = html_entity_decode($get_data);
$data= urlencode($b);
print_r($data);
$client = new SoapClient("https://api.betfair.com/global/v3/BFGlobalService.wsdl");
$result = $client->LoginReq($data);
print_r($result);
?>
I don't know why it's not working; can you help me out with this? Thank you in advance.
I would avoid using a dedicated SOAP library; in my experience they often don't work because of inconsistencies in the ways different servers implement the SOAP specification. Use a simple HTTP/HTTPS library instead, with the following headers
SOAPAction: urn:login
Content-Length: #{myContentLength}
Content-Type: text/xml
User-Agent: #{myUserAgent}
and the following payload (assuming you're using the Free API):
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 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">
<SOAP-ENV:Body>
<m:login xmlns:m="https://api.betfair.com/global/v3/BFGlobalService">
<m:request>
<username>#{myUsername}</username>
<password>#{myPassword}</password>
<locationId>0</locationId>
<vendorSoftwareId>0</vendorSoftwareId>
<productId>82</productId>
</m:request>
</m:login>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
It looks to me like you're using the wrong namespace for the login element; should be 'https://api.betfair.com/..' not 'http://www.betfair.com/..'.
Good luck.

Accessing XML content via PHP using SimpleXML

I am working with the XML file string below and I've tried a number of methods to try and get access to certain parts of the XML contents. Please see the code after the XML file below for my attempt:
<?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>
<Address_ListResponse xmlns="http://example.example.com/">
<Address_ListResult>
<Address>
<HoldingId xsi:nil="true"/>
<MainId>1617931</MainId>
<ContactId>8</ContactId>
<Description>Home, All Purposes</Description>
<Position/>
<Department/>
<Organisation/>
<AddressLabel>Mr Joe Bloggs</AddressLabel>
<AddressLine1>1 Fake Road</AddressLine1>
<AddressLine2/>
<AddressLine3/>
<Town>Faketown</Town>
<CountyId>818</CountyId>
<PostCode>FA33 4KE</PostCode>
<CountryId>3</CountryId>
<Phone>01234567890</Phone>
<EvePhone/>
<Mobile/>
<Email>joe#bloggs.com</Email>
<Fax/>
<WWW/>
<AddressTypeId>1</AddressTypeId>
<IsBilling>true</IsBilling>
<IsMailing>true</IsMailing>
<IsDelivery>true</IsDelivery>
<IsInherited>false</IsInherited>
<GridN/>
<GridE/>
<Latitude/>
<Longitude/>
<CensationCode/>
<IsDeleted>false</IsDeleted>
<HoldingPersonalDetailsId xsi:nil="true"/>
<IsSynced>false</IsSynced>
<BeenProcessed>false</BeenProcessed>
<CountyName/>
<CountryName/>
<AddressTypeName>Home</AddressTypeName>
</Address>
</Address_ListResult>
</Address_ListResponse>
</soap:Body>
</soap:Envelope>
Code for accessing the XML content:
$xml = simplexml_load_string($result);
echo "Town: " . $xml->children('http://schemas.xmlsoap.org/soap/envelope/')->children('http://example.example.com/')->Address_ListResponse->Town;
The above code was based on a link posted by another StackOverFlow question: http://blog.preinheimer.com/index.php?/archives/172-SimpleXML,-Namespaces-Hair-loss.html
Any help would be appreciated.
Thanks.
Consider using the SOAP extension instead.
See the example in the PHP Manual on how to write a client.
An alternative would be to use Zend_Soap as a standalone component.
Turns out the answer I was looking for wasn't SimpleXML - or at least I couldn't get that to work.
What I have done is used the xml_parse_into_struct to create an array of values returned from the XML data: http://www.php.net/manual/en/function.xml-parse-into-struct.php

Categories