I am trying to parse this complex SOAP response:
But I get lost with the namespaces and children methods...any idea how to extract the highlighted data?
I tried this:
$xml->children( $ns['S'] )->Body->children( $ns['ns7'] )->Answer->children( $ns['ns3'] );
but it doesn't work
You should use a WSDL to PHP generator which will ease you the request construction and response handling. Indeed, you'll handle PHP object with getters/setters which is better in my point of view.
I can only suggest you to try the PackageGenerator project.
Related
I am calling a API method through cURL and I got this response:
<?xml version="1.0" encoding="UTF-8"?>
<jobInfo
xmlns="http://www.force.com/2009/06/asyncapi/dataload">
<id>75080000002s5siAAA</id>
<operation>query</operation>
<object>User</object>
<createdById>00580000008ReolAAC</createdById>
<createdDate>2015-06-23T13:03:01.000Z</createdDate>
<systemModstamp>2015-06-23T13:03:01.000Z</systemModstamp>
<state>Open</state>
<concurrencyMode>Parallel</concurrencyMode>
<contentType>CSV</contentType>
<numberBatchesQueued>0</numberBatchesQueued>
<numberBatchesInProgress>0</numberBatchesInProgress>
<numberBatchesCompleted>0</numberBatchesCompleted>
<numberBatchesFailed>0</numberBatchesFailed>
<numberBatchesTotal>0</numberBatchesTotal>
<numberRecordsProcessed>0</numberRecordsProcessed>
<numberRetries>0</numberRetries>
<apiVersion>34.0</apiVersion>
<numberRecordsFailed>0</numberRecordsFailed>
<totalProcessingTime>0</totalProcessingTime>
<apiActiveProcessingTime>0</apiActiveProcessingTime>
<apexProcessingTime>0</apexProcessingTime>
</jobInfo>
I want to access|parse that result in a easy way and I don't know if I should deserializing the XML or just try to read it using some PHP native XML function. So ideas on this first doubt?
If it is better to deserialize the XML then I have read this post "Deserializing XML with JMSSerializerBundle in Symfony2" and is not clear at all for me if I will need an entity to achieve that. Also this other topic
and still confuse to me. Any advice on that? Experiences? Suggestions?
It depends on your intention. If you want to directly push part or all of the XML to an entity/document object for saving to a database then the JMSSerializerBundle can do this very smartly and is definitely the best way to do it.
If however you just want to extract one or two fields from the xml and use them in other business logic then simply loading the xml into a SimpleXML object is often simpler.
You can use any object (not only an entity) to deserialize the XML file to. It is recommended to deserialize to a object because you probably want to use it in an OOP way.
This is a well explained blog about JMS serializer (bundle) including a XML deserialization example in a user object: http://johnkary.net/blog/deserializing-xml-with-jms-serializer-bundle/
I have a generic HTTP file access API which I use for the system I'm working on. To make it as flexible as possible, it returns request and response data in the form of HTTP strings.
I'm currently implementing a version which interacts with the S3, via the AWS SDK for PHP 2.
Is there an easy way to quickly get the Request and Response HTTP requests which the S3Client makes when performing operations? If not, is there a more piecemeal way which I can use to not have to fake it?
Basically, I'd like the full-text of both the Request and Response on demand, or at least access to relevant data (headers, response codes, URLs, etc) so I can properly populate the return data for my framework.
Thanks.
You can get either the request or response object from a command object. Assuming $s3 holds an instance of Aws\S3\S3Client, you could do something like this:
$command = $s3->getCommand('ListObjects', array('Bucket' => '<bucket-name>'));
$request = $command->getRequest();
$response = $command->getResponse();
Those objects have methods for viewing the body, headers, status codes, etc. and you can cast them to string to see the string form.
If you want to quickly see the request and response as you are executing commands, you can attach the wire logger, and see what comes out on STDOUT (or STDERR)
$s3->addSubscriber(\Guzzle\Plugin\Log\LogPlugin::getDebugPlugin());
$s3->listObjects(array('Bucket' => '<bucket-name>'));
You will need to look into the Guzzle\Http\Client class, which is an ancestor class to S3Client, to have a look at the methods that it makes available. You can always override some of these methods in your own child of S3Client to make accessing this information easier for you.
Ultimately the data you are looking for resides in an object of class Guzzle\Http\Message\Response, which I believe is returned from Guzzle\Http\Client::send().
So perhaps in your own implementation of S3Client you can override the send() method to send the HTTP requests, then process the response data as needed.
Is it possible to input raw SOAP web service response ( read from file ) to the PHP SoapClient as string and get response object mapped in classmap?
Basicly same thing like usually SoapClient would be used, except I have response XML already.
Maybe you can create a local SOAP Server in PHP and call a method on it with your SOAP client. Then, you make the server method return your SOAP string by constructing it from objects, the proper way, or by using the quick and dirty approach: https://stackoverflow.com/a/8749213/1174378 which allows you to alter the contents of the SOAP message before sending it to the client.
I'm currently dealing with an archaic payment processor that makes connecting to their service as hard as possible (including a custom client SSL cert, with a password, plus basic HTTP Auth after that). Long story short, I can't use SoapClient to make the request, but I have been able to do it with cURL.
I now have the response in a string, can I use SoapClient to parse it? I'd rather not have to parse it manually as a regular XML, since I'd have to duplicate a lot of functionality, like throwing a sensible exception when finding a <SOAP:Fault>, for example.
No, you can't.
(just answering this for posterity. Based on the lack of evidence to the contrary, you apparently can't use SoapClient to parse a SOAP response you already have)
You can define context using context option of SoapClient to tell SoapClient to use SSL certificates etc. Context may be created using stream_context_create with lots of options
Let's for a second imagine you had called SoapClient::__doRequest() and it returned your XML SOAP response into a variable called $response.
<?php
//LOAD RESPONSE INTO SIMPLEXML
$xml = simplexml_load_string($response);
//REGISTER NAMESPACES
$xml->registerXPathNamespace('soap-env', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('somenamespace', 'http://www.somenamespace/schema/');
//...REGISTER OTHER NAMESPACES HERE...
//LOOP THROUGH AND GRAB DATA FROM A NAMESPACE
foreach($xml->xpath('//somenamespace:MessageHeader') as $header)
{
echo($header->xpath('//somenamespace:MyData'));
}
//...ETC...
?>
That is just some example/pseudo code (not tested and won't work as-is). My point is that you manually acquired the SOAP response so now all you have to do is parse it. SimpleXML is one solution you could use to do that.
I'm using the native SOAP class in PHP 5, having changed from NuSOAP as the native class is faster (and NuSOAP development seems to have ceased). However the PHP 5 SOAP lacks the ability to generate WSDL.
Has anyone experience of generating WSDL in PHP? If so, please recommend your preferred method.
Thanks.
Stuart,
If you or anyone else is looking for a solution to this problem here's what I did.
First get this script: http://www.phpclasses.org/browse/download/zip/package/3509/name/php2wsdl-2009-05-15.zip
Then look at its example files. After that I just sliced it the way I needed because I'm using codeigniter:
function wsdl(){
error_reporting(0);
require_once(APPPATH."/libraries/WSDLCreator.php"); //Path to the library
$test = new WSDLCreator("Webservice", $this->site."/wsdl");
//$test->includeMethodsDocumentation(false);
$test->addFile(APPPATH."/controllers/gds.php");
$test->addURLToClass("GDS", $this->site);
$test->ignoreMethod(array("GDS"=>"GDS"));
$test->ignoreMethod(array("GDS"=>"accessCheck"));
$test->createWSDL();
$test->printWSDL(true); // print with headers
}
That it, your all done.
Btw, I'm using SoapServer and SoapClient in php5+
You can try these options:
- https://code.google.com/p/php-wsdl-creator/ (GPLv3)
- https://github.com/piotrooo/wsdl-creator/ (GPLv3)
- http://www.phpclasses.org/package/3509-PHP-Generate-WSDL-from-PHP-classes-code.html (BSD like)
The first one might be your best option if the licence fits your project.
Generating a WSDL on the fly is not something that happens very often - it would tend to raise a few questions about the stability of your service!
Zend Studio can generate a WSDL from a PHP class, and there are a few other similar tools.
If you do need to generate the WSDL dynamically, take a look at Zend Framework library: Zend_Soap_AutoDiscover
Zend_Soap_AutoDiscover is a good alternative to NuSOAP. But, you can also create the WSDL file from scratch which can be very complicated and error prone. To ease this process, you can use an IDE to generate the WSDL file for your PHP functions and pass it as a parameter to your PHP SoapServer class. Check out the complete tutorial on How to generate wsdl for php native soap class