PHP SOAP Client - How to handle complex requests - php

I've done a few soap-client projects already but this time I am a bit stuck. I need to submit more then just an array this time - the XML looks like this:
<?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>
<InsertAddr xmlns="http://example.com/Service/">
<item>
<ID>long</ID>
<Text>string</Text>
<Fields>
<FieldItem>
<Name>string</Name>
<Value>string</Value>
</FieldItem>
<FieldItem>
<Name>string</Name>
<Value>string</Value>
</FieldItem>
</Fields>
</item>
</InsertAddr>
</soap12:Body>
</soap12:Envelope>
Normally I would call this like
$response = $client->InsertAddr(array('ID' => $submID, 'Text' => $submText, .....)
I've tried to submit id,text and an array with the fileds but it won't work.
Any advice what I should submit?
Thanks

I strongly advise you to use a WSDL to php generator so you won't wonder how to construct the request. In addition you'll handle the response very easily (depending on the generator you use).
You could try the PackageGenerator project which is very complete.

Related

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.

Return a php xpath answer with SOAP

I m trying to return an xpath answer to a soap client (i am using an xml file as database).
The method works fine when it's called on the server side, unfortunatelly, the client always get an annoying " looks like we got no XML document " error, with this kind of
xml answer:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn://localhost/projet/srv" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 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" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:getTypesVehiculeResponse>
<return SOAP-ENC:arrayType="SOAP-ENC:Struct[4]" xsi:type="SOAP-ENC:Array">
<item xsi:type="SOAP-ENC:Struct">
<#attributes xsi:type="ns2:Map">
<item>
<key xsi:type="xsd:string">id</key>
<value xsi:type="xsd:string">0</value>
</item>
...
</return>
</ns1:getTypesVehiculeResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Should I use another way to send my XML database answers than directly return xpath answer?
SoapClient should eliminate the need for xpath querying since it already parses the SOAP XML, but if you still want to use xpath, you can try using simplexml as per this answer. If you have an issue with namespaces, try this

how to get quotes with soap 1.2 in php?

I'm a complete noob in XML and SOAP,
Could you give some advice on at least where to start, or some example?
(I'm not begging to write code for me)
Here are the specs:
I just expect to receive two double values. What is an easiest way to do it?
POST /CurrencyConvertor.asmx HTTP/1.1
Host: www.webservicex.net
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?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>
<ConversionRate xmlns="http://www.webserviceX.NET/">
<FromCurrency>PHP</FromCurrency>
<ToCurrency>USD or EUR</ToCurrency>
</ConversionRate>
</soap12:Body>
</soap12:Envelope>
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?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>
<ConversionRateResponse xmlns="http://www.webserviceX.NET/">
<ConversionRateResult>double</ConversionRateResult>
</ConversionRateResponse>
</soap12:Body>
</soap12:Envelope>
The above specs's origin: http://www.webservicex.net/CurrencyConvertor.asmx?op=ConversionRate
The first block is supposed to be a request, and the other response...
EDIT
Alright, I stopped at a standard PHP class, but I don't quite understand what is being asked for in this __doRequest method:
$client = new SoapClient();
$client->__doRequest ( <<<EOD
<?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>
<ConversionRate xmlns="http://www.webserviceX.NET/">
<FromCurrency>PHP</FromCurrency>
<ToCurrency>USD or EUR</ToCurrency>
</ConversionRate>
</soap12:Body>
</soap12:Envelope>
EOD
, "http://www.webservicex.net/CurrencyConvertor.asmx" , $???, $??? );
http://www.php.net/manual/en/soapclient.dorequest.php
What is action, and what should I put as version, I know - a soap version 1.2 but the parameter is int so it cannot be assigned a 1.2 value lol...
EDIT2:
Alright, this is what I've got so far, but it gets me an empty string...
$client = new SoapClient(null, array('location'=>'http://www.webservicex.net/CurrencyConvertor.asmx','uri'=>''));
$client->__doRequest ( <<<EOD
<?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>
<ConversionRate xmlns="http://www.webserviceX.NET/">
<FromCurrency>PHP</FromCurrency>
<ToCurrency>USD or EUR</ToCurrency>
</ConversionRate>
</soap12:Body>
</soap12:Envelope>
EOD
, "http://www.webservicex.net/CurrencyConvertor.asmx" , "ConversionRate", 2 );
echo "Response :<br>", htmlentities($client->__getLastResponse());
...I just dont get this 'uri' thing - beyond my understanding. It makes me want to hit my head to the wall.
Basically what you need are two parts.
A SOAPClient class, which solves the communication, knows about the server URL, sends requests and receives responses (which you got in XML in your question) and also triggers #2, which is:
The second part is an XML parser / marshaller, which can convert a request objects (containing fromCurrency and toCurrency) to a correct XML string the server can understand (according to the WSDL) and convert some XML into a response object again using the WSDL. This part is a bit tricky, but I found a lot of documentation for that, search for "SOAP PHP" and you get some examples). These two processes are called marshalling and unmarshalling (to help you find something quicker with Google). Your StockQuote webservice doesn't really provide a WSDL, which is basically a description of all possible operations (in your case just one: GetQuote) and its available objects (in your case only simple types string, which don't have to be defined, since they are WSDL standard)
I haven't done SOAP with PHP, but spent a lot of time with Java+SOAP and can understand how difficult it is. In theory you just send some XML to the server and get some XML back. But the XML sent has to be in the correct format and when you receive a response, you want to convert the response into an object and not deal with some XML string.
For a simple web service like this, you might consider constructing the XML request by hand (simply putting together the XML string) and substr the response to find the requested answer.

Barnes and Noble seller SOAP API using PHP

I am new to SOAP and have been trying to connect to Barnes and Noble SOAP API using the php5 built in soap functions.
http://www.php.net/manual/en/class.soapclient.php
My question is, does anyone have any documentation or experience using Barnes and Noble system? I have been going back and forth with the support person and I feel like they assume we should just be able to figure it out.
The faultcode i am getting is "HTTP" and fault string is "Method Not Allowed".
Here is what the support guy says my header should look like.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<SessionInfo xmlns="http://tempuri.org/SessionInfoHeader">
<User xmlns="">your username goes here</User>
<Password xmlns="">your password goes here.</Password>
</SessionInfo>
</soap:Header>
This is as close as i can get it.
<?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:Header><ns1:SessionInfo>
<item>
<key>SessionInfo</key>
<value>
<item><key>User</key><value>[username]</value></item>
<item><key>Password</key><value>[password]</value></item>
</value>
</item>
</ns1:SessionInfo>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<searchCriteria/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I am not even sure this is the problem. Any help would be awesome.
In order to get the child nodes instead of the item key/value pairs you have to pass the parameter as an object.
$client = new SoapClient( 'test.wsdl' );
class SessionInfo {
public $User = 'test#example.com';
public $Password = '12345';
}
$sessionInfo = new SessionInfo();
$soap_headers = new SoapHeader( 'http://tempuri.org/SessionInfoHeader',
'SessionInfo', $sessionInfo );
$client->__setSoapHeaders( $soap_headers );
This will output what the support guy said should work. i think you could also create an array and type cast it to an object but i haven't tried that yet.

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