Implementing curl in ZF2 - php

I am trying to establish a communication with two zf2 application via curl.The required response is in xml. So far I could establish the connection and xml is returned as response.
The problem
The problem is that,I can't iterate on my xml response.Whenever I var_dump and view source code of my $response->getContent,I get as
string(142) "<?xml version="1.0" encoding="UTF-8"?>
<myxml>
<login>
<status>success</status>
<Err>None</Err>
</login>
</myxml>
"
and when I simply var_dump my $response,I get an object(Zend\Http\Response)#440.
simplexml_load_string($response->getContent()) gives me a blank page.
Also print $data->asXML() gives me Call to a member function asXML() on a non-object error.What am I doing wrong here?
Curl request action
$request = new \Zend\Http\Request();
$request->getHeaders()->addHeaders([
'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'
]);
$request->setUri('http://localhost/app1/myaction');
$request->setMethod('POST'); //uncomment this if the POST is used
$request->getPost()->set('curl', 'true');
$request->getPost()->set('email', 'me#gmail.com');
$request->getPost()->set('password', '2014');
$client = new Client;
$client->setAdapter("Zend\Http\Client\Adapter\Curl");
$response = $client->dispatch($request);
var_dump($response);//exit;
//$response = simplexml_load_string($response->getContent());
//echo $response;exit;
return $response;
Curl response action
$php_array=array(
'login'=>array(
'status'=>'failed','Err'=>'Unauthorised Access'
)
);
$Array2XML=new \xmlconverter\Arraytoxml;
$xml = $Array2XML->createXML('myxml', $php_array);
$xml = $xml->saveXML();
//echo $xml;exit;
$response = new \Zend\Http\Response();
$response->getHeaders()->addHeaderLine('Content-Type', 'text/xml; charset=utf-8');
$response->setContent($xml);
return $response;
The Array2XML can be found here
Any ideas?

when I simply var_dump my $response,I get an object(Zend\Http\Response)#440
This is correct and it tells you the type of $response.
simplexml_load_string($response->getContent()) gives me a blank page.
This is correct because despite this function can return a value expressible to an empty string, it does not create any output on it's own and therefore the blank page is to be expected.
Any ideas?
First of all you should formulate a proper problem statement with your question. All you say so far therein is to be expected, so your question is not clear at best.
Second you need to do proper error handling and do some safe programming:
$buffer = $response->getContent();
if (!is_string($buffer) || !strlen($buffer) || $buffer[0] !== '<') {
throw new RuntimeException('Need XML string, got %s', var_export($buffer, 1));
}
$xml = simplexml_load_string($buffer);
if (false === $xml) {
throw new RuntimeException('Unable to parse response string as XML');
}
Which is: For every parameter you get, validate it. For every function or method result you receive check the post-conditions. Before you call a function or method, check the pre-conditions for each parameter.
Log errors to file and handle uncaught exceptions.
As an additional idea: Drop the use of the array to XML function and replace it with a library that is maintained. In your case it's perhaps easier to just use SimpleXML your own to create the XML.

Related

Get a Soap request

Let me explain, I am doing something like a webservice in which I get information from a platform called Wialon, they use a section called repeaters where they send me a SOAP request to a specific address, I will be honest I have no idea how to use SOAP i never did something like this, so my question is how can i receive that SOAP data in PHP, so I can see it, I want to receive that SOAP request and i don't know save it in DB to see how it works or the structure, because these guys of wialon do not give information about what they send in that soap but I imagine it is an xml, so far I have tried to investigate but the truth is I do not know how soap works, im using this code that I found:
class MyClass {
public function helloWorld() {
require_once 'com.sine.controlador/Controlador.php';
$c = new Controlador();
$xml = $c->insertarResultado('06',func_get_args());
return 'Hello Welt ' . print_r(func_get_args(), true);
}
}
try {
$server = new SOAPServer(
NULL, array(
'uri' => 'http://localhost/WebserviceGLMS2/index.php'
)
);
$server->setClass('MyClass');
$server->handle();
} catch (SOAPFault $f) {
print $f->faultstring;
}
but it doesn't seem to work, hope you can help me, thanks
A soap request is nothing else than a xml post request. In PHP you can get the whole request body with the following code.
<?php
$content = file_get_contents('php://input');
var_dump($content);
You can use this unless it 's not multipart/formdata.

PHP SOAP service returns Value cannot be null. Parameter name: s

I'm trying upload orders to a remote server with soap but when I send the XML what the SOAP expects I got this error:
Exception: System.ArgumentNullException
Message: Value cannot be null.
Parameter name: s
Stack trace: at System.IO.StringReader..ctor(String s)
at System.Xml.XmlDocument.LoadXml(String xml)
I'm calling the service like this:
<?php
$doc = new DomDoument('1.0', 'UTF-8');
$doc->formatOutput = true;
/* lots of code here */
$xml = saveXML();
$client = new SoapClient('http://mx.biopont.com/services/Vision.asmx?wsdl',array("trace" => 1, 'features' => SOAP_SINGLE_ELEMENT_ARRAYS));
//$result = $client->RendelesFeladas(array('rendelesxml' => $xml));
try {
$result = $client->__soapCall('RendelesFeladas', array("rendelesxml"=>$xml));
}catch (SoapFault $e) {
echo "SOAP Fault: ".$e->getMessage()."<br />\n";
}
?>
the XML which is generated by DOMDocument is look like this
<?xml version="1.0" encoding="UTF-8"?>
<rendeles verzio="1.0">
<fej>
<partnerid>4476</partnerid>
<idegen_megrendelesszam>d836033</idegen_megrendelesszam>
<szallitasi_mod>51</szallitasi_mod>
<szallitasi_megj>gfhgfhgfhfhh</szallitasi_megj>
</fej>
<tetelek>
<tetel>
<tetelszam>1</tetelszam>
<cikkszam>102050009</cikkszam>
<mennyiseg>1</mennyiseg>
</tetel>
</tetelek>
</rendeles>
I don't have a clue what did i wrong. Because I construct the XML according to an example file which I got from the developer of the web-service. And actualy at the very first time I ran the call everything went fine since than I get error, and I didn't made changes to the xml, there were no changes in the SOAP service. So I don't get it.
Can somebody help me, point out what am I doing wrong?
Ok I found it.
For the partner who runs under the ID 4476 I added a fake ZIP code and the soap service couldn't figure out what to do whit it so the user 4476 was corrupted. After I updated the address information the order was accepted by the soap service.

Check if an xml is loaded with simplexml_load_string

I am querying an xml file with php like this :
public function trackOrderAction()
{
$request = Mage::getResourceModel( 'order/request' );
$request->setOrder($this->getRequest()->getParam('increment_id'));
$response = $request->submit(true);
$xml = simplexml_load_string($response);
$items = count($xml->OrderItems->OrderItem);
}
The xml is not ready immediately so if people try to use the function before it is ready there is an error because it is trying to get the property of a non-object. My question is what is the proper way to check the xml response to see if there is anything and stop the function if there is not?
I tried something simple like
if (empty($xml)){
die();
} else {
$items = count($xml->OrderItems->OrderItem);
}
But this does not help. Any ideas on how to check to see if the xml loaded?
From http://us.php.net/manual/en/function.simplexml-load-string.php
Returns an object of class SimpleXMLElement with properties containing
the data held within the xml document. On errors, it will return
FALSE.
public function trackOrderAction()
{
$request = Mage::getResourceModel( 'order/request' );
$request->setOrder($this->getRequest()->getParam('increment_id'));
$response = $request->submit(true);
$xml = simplexml_load_string($response);
if ( !$xml ) {
return false;
}
$items = count($xml->OrderItems->OrderItem);
}
It will return false if there was an error. So fail right away if simplexml_load_string fails and return false. Otherwise continue on with the rest of the function. Never die() in a function.

What is the best method to receive, process, and then return XML data using PHP?

I need to create a PHP script that receives XML input via an HTTP POST request, processes it, and then returns an XML response. I have spent quite a while attempting this on my own, and here is what I have so far.
I first quickly threw together an HTML form that allows a user to submit XML data as a string, an XML URI as a string, or an XML URI to my PHP script. This form is for testing only, as I am only tasked with creating this script.
In my PHP script I do some input handling...
// Checks that some XML input has been given
if (!(isset($_POST['xmlinput']))) {
handleErrors("No XML Input Given");
}
// Creates a new DOM Document
$domdoc = new DomDocument;
// Sets the URL of the XML Schema
$xmlschema = "xmlschema.xsd";
// If XML input is a file, tries to load it
if (file_exists($_POST['xmlinput'])) {
if (!$domdoc->load($_POST['xmlinput'])) {
handleErrors("Error in XML File");
}
}
// If XML input is not a file, tries to load it as a string
else {
if (!$domdoc->loadXML($_POST['xmlinput'])) {
handleErrors("Error in XML Document");
}
}
// Validates the XML against the schema
if (!($domdoc->schemaValidate($xmlschema))) {
handleErrors("XML Does Not Conform To Schema");
}
I then do some stuff based on what the XML data is, and then I want to generate an XML response. I am fairly certain I can create XML in DOM or SimpleXML, but I simply do not understand how to return it to the original page. Also, is this the best method to handle XML input in PHP? I have seen a ton of posts about php://input or $HTTP_RAW_POST_DATA but these don't seem to be any better than the method I use. Any information you can give me would be a big help. If I can clarify any more, just let me know.
Very simply, you create your xml document using SimpleXml,
then just
echo $xml->asXML();
If you need to post xml data to a webservice,
You can use the following code to acheive that.
function do_post_request($url, $data, $optional_headers = null)
{
$params = array('http' => array(
'method' => 'POST',
'content' => $data
));
if ($optional_headers !== null) {
$params['http']['header'] = $optional_headers;
}
$ctx = stream_context_create($params);
$fp = #fopen($url, 'rb', false, $ctx);
if (!$fp) {
throw new Exception("Problem with $url, $php_errormsg");
}
$response = #stream_get_contents($fp);
if ($response === false) {
throw new Exception("Problem reading data from $url, $php_errormsg");
}
return $response;
}
You dont want to use the Error Suppression Operator but add the proper Option for that:
$dom = new DOMDocument;
$dom->loadXML($source, LIBXML_NOERROR);
An alternative would be to use libxml_use_internal_errors.
A response is basically just what the webserver sends back to the requesting client, so to send an XML response, you simply echo your XML it with an XML header, e.g.
header ("Content-Type:text/xml; charset=utf-8");
echo $xml->asXML();

Strange problems with PHP SOAP (private variable not persist + variables passed from client not working)

I have a very strange problems in a PHP Soap implementation.
1) I have a private variable in the Server class which contains the DB name for further reference. The private variable name is "fromdb". I have a public function on the soap server where I can set this variable. $client->setFromdb. When I call it form my client works perfectly and the fromdb private variable can be set. But a second soap client call this private variable loses its value... Here is my soap server setup:
ini_set('soap.wsdl_cache_enabled', 0);
ini_set('session.auto_start', 0);
ini_set('always_populate_raw_post_data', 1);
global $config_dir;
session_start();
/*if(!$HTTP_RAW_POST_DATA){
$HTTP_RAW_POST_DATA = file_get_contents('php://input');
}*/
$server = new SoapServer("{$config_dir['template']}import.wsdl");
$server->setClass('import');
$server->setPersistence(SOAP_PERSISTENCE_SESSION);
$server->handle();
2) Problem is that I passed this to the server:
$client = new SoapClient('http://import.ingatlan.net/wsdl', array('trace' => 1));
$xml='<?xml version="1.0" encoding="UTF-8"?>';
$xml.='<xml>';
$xml.='<referens>';
$xml.='<original_id><![CDATA[DH-2]]></original_id>';
$xml.='<name>Valaki</name>';
$xml.='<email><![CDATA[valaki#example.com]]></email>';
$xml.='<phone><![CDATA[06-30/111-2222]]></phone>';
$xml.='</referens>';
$xml.='</xml>';
$tarray = array("type" => 1, "xml" => $xml);
try {
$s = $client->sendXml( $tarray );
print "$s<br>";
}
catch(SOAPFault $exception) {
print "<br>--- SOAP exception :<br>{$exception}<br>---<br>";
print "<br>LAST REQUEST :<br>";
var_dump($client->__getLastRequest());
print "<br>---<br>";
print "<br>LAST RESPONSE :<br>".$client->__getLastResponse();
}
So passed an Array of informations to the server. Then I got this exception:
LAST REQUEST :
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><type>Array</type><xml/></SOAP-ENV:Body></SOAP-ENV:Envelope>
Can you see the Array word between the type tag? Seems that the client only passed a reference or something like this. So I totally missed :(
It seems the SOAP extension is expecting a string, but you're giving it an array. It then tries to convert the array into a string, resulting in "Array". I don't have time to check right now what the extension does you write $client->sendXml( $tarray );, but try to use instead:
$client->__soapCall("sendXml", $tarray);

Categories