Reading a Simple SOAP XML response in PHP - php

I have looked for a solid working answer on this can't find one.
I am also New at SOAP, but very familiar with PHP.
I send out my SOAP request with CURL and my response comes back 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>
<GetFeatureResponse xmlns="http://www.supportsite.com/webservices/">
<GetFeatureResult>**string**</GetFeatureResult>
</GetFeatureResponse>
</soap:Body>
</soap:Envelope>
I need to save the ->GetFeatureResult 'string' in a MySQL database without the XML. Everything I try returns blank. Here's what I'm using now:
$result = curl_exec($curl);
curl_close ($curl);
$resultXML = simplexml_load_string($result);
$item = $resultXML->GetFeatureResponse->GetFeatureResult;

PHP has a built in soap client. It is a LOT easier. As long as you point it to a proper WSDL file, it will return a PHP object ready to use.
EDIT: Dug up an example I had around...
$sc = new SoapClient($wsdl, array(
'location' => "https://$host:$port/path/",
'login' => $user,
'password' => $pass
));
//$sc will now contain methods (maybe properties too) defined by the WSDL file
//Getting the info you need could be as easy as
$info = $sc->getInfo(array('parameter'=>'value'));

Related

Soap insert request xml format from powershell

i'm trying to make a soap service that is capable of inserting certain values into a microsoft sql database, the server is php and the client calls the server from powershell.
So i have a Soap server setup with NuSOAP and a number of methods, these methods are made like this:
$server->register('InsertInDb',
array('query' => 'xsd:string'), // parameter
array('return' => 'xsd:string'), // output
'urn:server', // namespace
'urn:server#helloServer', // soapaction
'rpc', // style
'encoded', // use
'the query you want to execute');
now i can call this method with the following code from the powershell client:
$url = ".../NuSoapServerTest.php?wsdl"
$proxy = New-WebServiceProxy $url
$proxy | gm -memberType Method
$proxy.InsertInDb('Insert into value etc...')
however i want to be able to execute a method like this
$url = ".../NuSoapServerTest.php?wsdl"
$soap = [xml]#'
<?xml version="1.0" encoding="utf8"?>
<soap:Envelope xmlns:xsi=".../NuSoapServerTest.php?wsdl">
<soap:Body>
<inventory>
<machine>
<systemname>example value</systemname>
</machine>
<hardware>
<machine_type>example value</machine_type>
</hardware>
</inventory>
</soap:Body>
</soap:Envelope>
'#
$ret = Execute-SOAPRequest $soap $url;
with each <'tag'> meaning a layer in the database.
i've been looking around the web a lot for examples but as of yet i haven't found any examples that make it clear to me how i can set either the server or client up to execute my methods in the demonstrated way.
Maybe i am misunderstanding the principals of SOAP and how its supposed to work or i'm just being dumb but any help would be appreciated
edit: it might be worth noting this is the first time i am working with powershell.

PHP SOAP request - get empty result

I wanto to get data from SOAP API. More details is here:
https://iskam-web.zcu.cz/WebServices/Menus.asmx?op=Facilities
Here are request informations:
and my PHP code looks like this:
$soap = new SoapClient("https://iskam-web.zcu.cz/WebServices/Menus.asmx?wsdl");
$xml = $soap->Facilities(array());
print "<pre>";
print_r($xml);
print "</pre>";
but the answer I get looks like this:
so it means the result is empty. Is there something what am I doing wrong or the API is just not working?
Thank you!
Facilities method in that wsdl it does not specify anything not even what data needs to be passed. Simply you are not doing anything wrong but the Facilities method returns an empty object. Meaning no data.
This is the xml response from Facilities:
<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>
<FacilitiesResponse xmlns="http://aps-brno.cz/"/>
</soap:Body>
</soap:Envelope>
In this case I suggest to reach some support from the web service's support.
If you try to call
$soap = new SoapClient("https://iskam-web.zcu.cz/WebServices/Menus.asmx?wsdl");
$response = $soap->DistributionPeriods(['FacilityID' => '123123123123123-123123123-123123123', 'Day' => '4']);
print "<pre>";
print_r($response);
print "</pre>";
Will ask you to pass an Facility ID formatted like: Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) . That way I believe you will get some data back.

Pass raw xml to SOAP in 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.

Stuck at converting xml request to corresponding Savon request

I am trying to communicate with a 3-rd party API. I tried both savon and Soap UI but both failed, then I asked them and they gave me equivalent that works. Confused, I toggled the logger and got following XML request which is quite different from what Savon is sending.
Here is the PHP code (I guess that's not needed, but still)
$apiauth =array('UserName'=>'XXXXXX','Password'=>'XXXXXXX','ClientCode'=>'1234')
$wsdl = 'http://stagewebapi.mylescars.com/service.asmx?wsdl';
$soap = new SoapClient($wsdl);
$header = new SoapHeader('http://tempuri.org/', 'AuthHeader', $apiauth);
$soap->__setSoapHeaders($header);
$data = $soap->fetchCities($header);
print_r($data);
Here is the XML request that PHP is sending and which is working just fine
<?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:AuthHeader><ns1:UserName>XXXXXXX</ns1:UserName><ns1:Password>XXXXXXX</ns1:Password><ns1:ClientCode>1234</ns1:ClientCode></ns1:AuthHeader></SOAP-ENV:Header><SOAP-ENV:Body><ns1:fetchCities/></SOAP-ENV:Body></SOAP-ENV:Envelope>
Here is my ruby code so far
require 'savon'
auth_header = { 'UserName'=>'XXXXXXX','Password'=>'XXXXXXXX','ClientCode'=>'1234'}
client = Savon.client(:wsdl => "http://stagewebapi.mylescars.com/service.asmx?wsdl",
:namespace_identifier => :ns1 ,:namespace => "http://tempuri.org/" , :log => true, :soap_header => auth_header,
:pretty_print_xml => true, :env_namespace => 'SOAP-ENV')
puts client.call(:fetch_cities)
Here is what Savon is producing
<?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:ns1="http://tempuri.org/" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header>
<UserName>XXXXXXXXXXXXXXX</UserName>
<Password>XXXXXXXXXXXXX</Password>
<ClientCode>2873</ClientCode>
</soap-env:Header>
<soap-env:Body>
<ns1:fetchCities/>
</soap-env:Body>
</soap-env:Envelope>
I don't know how to make it equivalent to the PHP one. Am I missing something obvious ?
I tried to look at Savon documentation to find if there are some methods to manipulate tags with fine grain control but couldn't find much about it.
Questions similar to this are either unanswered or are specific to the requests.
Some SO questions that helped a little
Convert this xml request to a proper savon request
Replicating xml requests with savon ruby
Little curious, how PHP gets it right most of the time. Is it the parser they use for wsdl?

Problems in using PHP Soap Client

I have this web service to access with this kind of configuration:
<?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>
<Executar xmlns="http://localhost/I9ProWebService">
<Servico>string</Servico>
<conteudoXML>string</conteudoXML>
</Executar>
</soap:Body>
</soap:Envelope>
So I tried this:
$client = new soapclient('https://domain/webservice/I9ProWebService.asmx?WSDL');
printf($client->Executar("ListarTomador","<i9proerp><listar_tomador id_pessoa_corretor =\"205\" /></i9proerp>"));
it shows this error:
System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.NullReferenceException: Object reference not set to an instance of an object. at I9ProWebService.Executar(String Servico, String conteudoXML) --- End of inner exception stack trace ---
Have you tried using htmlentities or similar to encode the XML you are sending as your second parameter? That might be causing problems with the XML sent by the SOAP client.
EDIT: In order to see what XML the PHP SOAP client is sending and what it's getting back, you can use $client->__getLastRequest() and $client->__getLastResponse() and compare the results with your soapUI call.
I found the solution of my problem.
$client = new SoapClient("http://domain/webservice/I9ProWebService.asmx?WSDL", array("features" => SOAP_SINGLE_ELEMENT_ARRAYS, "encoding" => "utf-8","trace"=> TRUE));
$strVariavel = "<ns1:conteudoXML><i9proerp><listar_tomador id_pessoa =\"999\"/></i9proerp></ns1:conteudoXML>";
$soapvar = new SoapVar($strVariavel, 147);
$xml = $client->ExecutarXML(array('Servico'=>'ListarTomador','conteudoXML'=>$soapvar));
print_r($xml);
and voilá
The problem is that it returns and object and not a XML as I expected...
It returns:
stdClass Object
(
[ExecutarXMLResult] => stdClass Object
(
[any] => <i9proerp xmlns=""><listatomador id_pessoa="5251" nm_pessoa="nome1" nr_cnpj_cpf="132132121332"/><listatomador id_pessoa="939" nm_pessoa="nome2" nr_cnpj_cpf="3213213123213"/></i4proerp>
)
)
So, I have to discover how to deal with it. Is it a case to open another question?

Categories