I've been working on an API for receiving a XML file which in turn gonna be read in our databse. The parsing and all worked with local XML files. Now the last step was to check if the receiving of the XML was working and there is where I hit a roadblock. Been trying a lot of different things up untill now, but can't seem to get it to work. We would prefer to work with the REST method, but if it's really not gonna work we're willing to switch it up. Seen a lot of questions for sending or receiving a XML file, but never in combination. So hope I can get a solid answer on this and didn't miss a question that is a duplicate.
TL;DR: Sending and receiving XML files through PHP, don't know where I'm making a error
The sending and receiving parts are in different scripts.
//Sending XML script.
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_MUTE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml',
'Content-length: '.strlen($xmlSend)));
curl_setopt($ch, CURLOPT_POSTFIELDS, array("recXML" => $xmlSend));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
//Receiving XML script
if(isset($_REQUEST['recXML'])){
$xmlTest = $_REQUEST['recXML'];
} else {
echo "NO REQUEST XML FOUND ";
}
if(isset($HTTP_RAW_POST_DATA)){
$xmlTest = $HTTP_RAW_POST_DATA;
} else {
echo " NO RAW DATA ";
}
if(isset($_POST['recXML'])){
$xmlTest = $_POST['recXML'];
}else{
echo " NO XML RECEIVED ";
}
if(!isset($xmlTest)){
return;
}
This is not the complete logic, but I think these are the parts that matter, if you want more code just ask.
EDIT:
after some changes and restarting my pc, it finally worked. So not exactly sure which change fixed the problem, but will post the code below in case anyone could ever find use for it.
//Sending script:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/xml',
'Content-length: '.strlen($xml)));
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
//receiving script
$xmlTest = file_get_contents("php://input");
echo $xmlTest;
$res = simplexml_load_string($xmlTest);
if($res === false){
echo "Failed loading XML: ";
foreach(libxml_get_errors() as $error){
echo "<br>", $error->message;
}
return;
} else {
//print_r($res);
}
You should send content-Type as application/xml
so your code will become
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/xml',
'Content-length: '.strlen($xmlSend)));
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlSend);
and on receiving side you can use
$xml = file_get_contents("php://input");
For your current code you can set content-type as application/x-www-form-urlencoded the you can use $_POST['recXML']
Related
I am calling an API using CURL.
When I run it directly in browser or via ajax request it runs well and gives xml output.The Api am calling stores the xml in a database table and would only then work well.
However when I call it via PHP curl their table is not getting updated.
The code am doing it with PHP curl is
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
$headers = array();
$headers[] = "Accept: application/json";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
Sample URL : http://example.com/code=x05a&businessKeyValue=8519ada0-9e2f-e265-8698-5b6145af9704&entity=funded_program_concession¶meters=fpc_funded_program_concession_id%7C8519ada0-9e2f-e265-8698-5b6145af9704¶meters=fps_funded_program_subsidy_id%7Cf320f2d9-7c6a-0b56-2940-5b61147a0f3d
If I open this link which opens it in browser, it works good, but if I run it via curl the API is not receiving xml content.
How can I resolve this issue?
$api='http://example.com/code=x05a&businessKeyValue=8519ada0-9e2f-e265-8698-5b6145af9704&entity=funded_program_concession¶meters=fpc_funded_program_concession_id%7C8519ada0-9e2f-e265-8698-5b6145af9704¶meters=fps_funded_program_subsidy_id%7Cf320f2d9-7c6a-0b56-2940-5b61147a0f3d';
$ch = curl_init();
$headers = array();//put your headers only if you need them
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result= curl_exec($ch);
return $result;
This should work for you. Inside your headers array make sure you put the headers you need and not extra. This is a simple curl, get call so i guess the above code will work without any trouble.
If you want to accept xml then you can got for Accept:application/xml or Accept:application/xhtml+xml
If the above methods don't work provide us with your error.
echo 'Curl error: ' . curl_error($ch);
Add the above line as a breaking point in your code and see what's the error.
I'm trying to do the bare minimum, just to get it working.
Here is my Google Script:
function doPost(e) {
return ContentService.createTextOutput(JSON.stringify(e.parameter));
}
Here is my PHP code:
$url = 'https://script.google.com/a/somedomain.com/macros/s/### script id ###/exec';
$data['name'] = "Joe";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: multipart/form-data"));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec($ch);
$error = curl_error($ch);
Executing this, $result is true.
If I uncomment the CURLOPT_RETURNTRANSFER line, $result =
<HTML>
<HEAD>
<TITLE>Bad Request</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Bad Request</H1>
<H2>Error 400</H2>
</BODY>
</HTML>
$error is always empty.
I would use doGet() but I need to send some rather large POSTs that will exceed what GET can handle.
How can I post to a Google script and return data?
------ UPDATE ------
I've just learned my lead developer tried this some time ago and concluded doPost() errors when returning so apparently it's not just me. My take is that Google is simply not reliable enough to use. I would love for someone to prove me wrong.
------ UPDATE 2 - THE FIX ---------
Apparently this was the problem:
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
needs to be:
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
No idea why http_build_query() caused it to error.
Try reading the documentation for CURLOPT_POSTFIELDS and you'll see that is says To post a file, prepend a filename with # and use the full path. That looks what you are trying to do. Note that in php 5.5, the CURLFile class was introduced to let you post files.
If you are using php 5.5 or later, you might try this:
$url = 'https://script.google.com/a/somedomain.com/macros/s/### script id ###/exec';
// create a CURLFile object:
$cfile = new CURLFile('file.pdf','application/pdf'); // you can also optionally use a third parameter
// your POST data...you may need to add other data here like api keys and stuff
$data = array("fileName" => $cfile);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: multipart/form-data"));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
// FROM THE DOCS:
// If value is an array, the Content-Type header will be set to multipart/form-data (so you might skip the line above)
// As of PHP 5.2.0, value must be an array if files are passed to this option with the # prefix
// As of PHP 5.5.0, the # prefix is deprecated and files can be sent using CURLFile
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
// set this to TRUE if you want curl_exec to retrieve the result
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec($ch);
if ($result === FALSE) {
echo "The result is FALSE. There was a problem\n";
$error = curl_error($ch);
var_dump($error);
die();
} else {
echo "success!\n";
var_dump($result);
}
// this can give you more information about your request
$info = curl_getinfo($ch);
if ($info === FALSE) {
echo "curlinfo is FALSE! Something weird happened";
}
var_dump($info); // examine this output for clues
EDIT: If you are not getting any error, and $result comes back with something like "Bad Request" then you will need to inspect the result more closely to find out what the problem is. A well-behaved API should have informative information to help you fix the problem. If the API doesn't tell you what you did wrong, you can examine the curlinfo you get from these commands:
$info = curl_getinfo($ch);
var_dump($info); // examine this output for clues
if $result and $info don't tell you what you've done wrong, try reading the API documentation more closely. You might find a clue in there somewhere.
If you can't figure out what the problem is using these tactics, there's not much else you can do with your code. You'll need more information from the maintainers of the API.
You need to look at your HTTP Request header to see what is actually being posted.
When trouble shooting I add these options:
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT,10);
curl_setopt($ch, CURLOPT_FAILONERROR,true);
curl_setopt($ch, CURLOPT_ENCODING,"");
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
CURLINFO_HEADER_OUT will add "request_header" to curl_getinfo()
You also want to look at these curl_getinfo() elements.
request_size
size_upload
upload_content_length
request_header
How do I make a retry of three attempts on a failed PHP Curl call? I notice that my code seems to stop working. I tried using a curl_error, but no success. The code is listed below:
<?php
$url = 'http://somewhere.com/api/';
//set up parameters to pass via POST
$data = array('param1' => 'Parameter 1');
$data_json = json_encode($data);
$return = '';
$ctr = 0;
$ch = curl_init($url);
//I want to have a retry of three times
while($ctr++ < 3){
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Content-Length: ' . strlen($data_json)));
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$result = curl_exec($ch);
if(curl_error($ch)){
//try again
}
else{
$obj=json_decode($result);
$return = $obj->{'return'};
}
}
curl_close ($ch);
?>
I was hoping that the timeout of 10 (seconds?) would force the Curl call to terminate.
The JSFiddle link is at https://jsfiddle.net/jun3178_dolor/feqyz2vp/
PHP's cURL extension does not include the retry flags (See --retry at https://curl.haxx.se/docs/manpage.html). You have to manually code in a custom ability to look for the response code (https://www.php.net/manual/en/function.curl-getinfo.php) or last error number via https://www.php.net/manual/en/function.curl-errno.php.
I've answered this question due to the page being a top result for "php curl retry".
I am trying to post json data with cURL. The idea is: In case the url is not accessible ( for example failure of internet connection) keep trying to post the json while you succeed. It works but when I put it in while loop it executes only once. What am I doing wrong:
$jsonDataEncoded = json_encode($event);
echo $jsonDataEncoded;
echo "\n";
$send_failure = true;
while ($send_failure) {
$url = "a";// intentionally inaccessible url
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($jsonDataEncoded)));
$result = curl_exec($ch);
if(curl_errno($ch)){
throw new Exception(curl_error($ch));
} else {$send_failure = false;}
return $result;
}
You must print and check the value in $result using var_dump($result); .
If there is any connection error it returns the error code which you can check manual in IF condition. Hope this might help you.
I am trying to connect to an echosign api which used to work and now has suddenly stop working, I have tried debugging but can't seem to resolve it, this is my code
public function get_access_token_get()
{
$echoSign = new EchoSign();
$ch = curl_init('https://secure.echosign.com:443/api/rest/v2/auth/tokens');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($echoSign->echosign_creds));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$result = json_decode(curl_exec($ch));
curl_close($ch);
echo "<pre>"; print_r($result); echo "</pre>"; exit();
return $result->accessToken;
}
I have tested your curl code with other urls, and its working fine for them, then i tried to call your url with other curl methods and it gives empty response, so I believe you should check with the echosign support to see whats wrong.