I'm trying to download a file, which URL I get from a webhook:
<?php
$webhookResponse = json_decode(file_get_contents('php://input'), true);
//The resource that we want to download.
$fileUrl = $webhookResponse["data"]["orderDetails"][0]["detailFiles"][0]["fileUrl"];
//The path & filename to save to.
$saveTo = 'test.pdf';
//Open file handler.
$fp = fopen($saveTo, 'w+');
//If $fp is FALSE, something went wrong.
if($fp === false){
throw new Exception('Could not open: ' . $saveTo);
}
//Create a cURL handle.
$ch = curl_init($fileUrl);
//Pass our file handle to cURL.
curl_setopt($ch, CURLOPT_FILE, $fp);
//Timeout if the file doesn't download after 20 seconds.
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
//Execute the request.
curl_exec($ch);
//If there was an error, throw an Exception
if(curl_errno($ch)){
throw new Exception(curl_error($ch));
}
//Get the HTTP status code.
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
//Close the cURL handler.
curl_close($ch);
//Close the file handler.
fclose($fp);
if($statusCode == 200){
echo 'Downloaded!';
} else{
echo "Status Code: " . $statusCode;
}
?>
When I try to run it, it gives me an error:
Trying to access array offset on value of type null
This is how my array looks that I get from webhook:
Interesting thing, if I put this same script on another server, it works fine, it downloads the file, if I put it one the actual one I need to use (ubuntu, nginx) it gives me this error, could this be a little server related?
Related
I've been trying for a few days to be able to call a url on a remote server that automatically downloads an Excel file when you put the url into a browser. I made a page locally that automatically downloads the file for testing, but I cannot get cURL to do it. The script returns no errors and says it was successful, but the file it writes to becomes corrupt and opens blank.
Here is the code...
$output_file = 'E:\Downloads\Export.xlsx';
$download_url = 'http://localhost/test/urlexport.php';
$ch = curl_init();
$out = fopen($output_file, 'w');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FILE, $out);
curl_setopt($ch, CURLOPT_URL, $download_url);
$output = curl_exec($ch);
fwrite($out, $output);
if(curl_exec($ch) === false)
{
echo 'Curl error: ' . curl_error($ch);
}
else
{
echo 'Operation completed without any errors';
}
if(curl_errno($ch)){
echo 'Curl error: ' . curl_error($ch);
}
curl_close($ch);
I've spent quite a bit of time researching this but have yet to find an answer that actually works. Any help is appreciated, thanks.
If you're not sure what you're doing - keep it simple.
Here's the simplest possible way to do what you're doing, which is downloading a file and then saving it to disk.
<?php
$output_file = 'E:\Downloads\Export.xlsx';
$download_url = 'http://localhost/test/urlexport.php';
$file = file_get_contents($download_url);
file_put_contents($output_file, $file);
If this doesn't work then your download url isn't doing what you think it's doing. Take a look at what's actually in the $output_file (open it in a text editor) - maybe it's some html.
I am trying to senddata to a url by using curl with codeigniter. I have successfully implemented the code for sending the data as below.
function postToURL($reg_no, $data)
{
$url = 'http://localhost/abcSystem/Web_data/viewPage';
$send_array = array(
'reg_no' =>$reg_no,
'data' =>$data,
);
$fields_string = http_build_query($send_array);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 600);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_REFERER, $url);
$post_data = 'json='.urlencode(json_encode($send_array));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$output = curl_exec($ch);
if (curl_errno($ch)) {
die('Couldn\'t send request: ' . curl_error($ch));
} else {
$resultStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($resultStatus == 200) {
print_r('success'); // this is outputting
return $output;
} else {
die('Request failed: HTTP status code: ' . $resultStatus);
}
}
curl_close($ch);
}
The out put is success. I want to see if this post data can be retrieved. So I tried to change the above url controller file as below.
$fp = fopen('php://input', 'r');
$rawData = stream_get_contents($fp);
echo "<pre>";
print_r($rawData);
echo "</pre>";
But nothing is printing. I want to get the data of posting. Please help me on this.
Your Written code
$fp = fopen('php://input', 'r');
$rawData = stream_get_contents($fp);
echo "<pre>";
print_r($rawData);
echo "</pre>";
is not to Print or capture Posted Data . Because you are dealing with Current Page PHP INPUT Streaming , whereas you are posting data on Other URL . So what you need to do is just Put a log of posted data in File. Use below code after $output = curl_exec($ch)
file_put_contents("posted_data.txt", $post_data );
This way you will be able to write your each post in file Posted_data.txt File - Make sure you give proper File Permission. If you want to keep trace of each POST than just make the file name dynamic so per API Call it can write a log.
Another option is to save the $post_data in DATABASE - Which is not suggestable from Security point of view.
Where ever you are calling your postToURL() function, you need to output the result of it.
For example:
$output = postToURL('Example', array());
echo $output;
This is because you are returning the curl output rather outputting it.
If the following PHP is runnig, I would like to download the file with `cURL on the client-site. It means, if one of my website visitor run's an action, which starts this PHP file, it should download the file on this PC.
I tried with different locations, but without any success. If I run my code, it does always download it on my WebSever, which is not this, what I want.
<?php
//The resource that we want to download.
$fileUrl = 'https://www.example.com/this-is-a-example-video';
//The path & filename to save to.
$saveTo = 'test.mp4';
//Open file handler.
$fp = fopen($saveTo, 'w+');
//If $fp is FALSE, something went wrong.
if($fp === false){
throw new Exception('Could not open: ' . $saveTo);
}
//Create a cURL handle.
$ch = curl_init($fileUrl);
//Pass our file handle to cURL.
curl_setopt($ch, CURLOPT_FILE, $fp);
//Timeout if the file doesn't download after 20 seconds.
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
//Execute the request.
curl_exec($ch);
//If there was an error, throw an Exception
if(curl_errno($ch)){
throw new Exception(curl_error($ch));
}
//Get the HTTP status code.
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
//Close the cURL handler.
curl_close($ch);
if($statusCode == 200){
echo 'Downloaded!';
} else{
echo "Status Code: " . $statusCode;
}
?>
How can I change the cURL downloading process to the client-site?
PHP cannot run client-side.
You could use cURL to download data to the server (without saving it to a file) and then output that data to the client.
Don't do this:
//Open file handler.
$fp = fopen($saveTo, 'w+');
or this:
//Pass our file handle to cURL.
curl_setopt($ch, CURLOPT_FILE, $fp);
Then capture the output:
//Execute the request.
curl_exec($ch);
Should be:
//Execute the request.
$output = curl_exec($ch);
Then you can:
echo $output;
… but make sure you set the Content-Type and consider setting the Content-Length response headers. You might also want Content-Disposition.
Under most circumstances, it would probably be better to simply send the browser to fetch the file directly instead of proxying it through the server.
$fileUrl = 'https://www.example.com/this-is-a-example-video';
header("Location: $fileUrl");
I need to receive image send by PUT method. So I'm wrinting script for testing it. I want to receive and send it with the same script. How can I implement this? The following variant echoes nothing and string about Congratulations that http method was send ok.
<?php
//if they DID upload a file...
var_dump(file_get_contents("php://input"));
if($_FILES['photo']['tmp_name'])
{
echo $_FILES['photo']['error'];
if($_FILES['photo']['error']==0)
{
//now is the time to modify the future file name and validate the file
$new_file_name = strtolower($_FILES['photo']['tmp_name']); //rename file
$message = 'Congratulations!!!!!!!.';
//move it to where we want it to be
move_uploaded_file($_FILES['photo']['tmp_name'], 'url.../1.jpg');
echo'Congratulations! Your file was accepted.';
$image = fopen('url.../1.jpg', "rb");
var_dump($image);
$ch = curl_init();
/* Set cURL options. */
curl_setopt($ch, CURLOPT_URL, "http://url.../upload.php");
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, $image);
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($image));
/* Execute the PUT and clean up */
$result = curl_exec($ch);
fclose($image); //recommended to close the fileshandler after action
curl_close($ch);
}
//if there is an error...
else
{
//set that to be the returned message
$message = 'Ooops! Your upload triggered the following error: '.$_FILES['photo']['error'];
}
}
else
{
echo"WORKS";
}
The most easiest way to send back the image to a browser is via using a URL.
Process the image
Save the image somewhere on your sever
Send the URL back to browser.
Use a tag at the browser and show your image.
<?PHP
$imgFile="";
if($_FILES['photo']['tmp_name'])
{
///Your existing code
$imgFile="http://" . $_SERVER['HTTP_HOST'] .'/Your image url here';
//Ex:\\ http://yourserver.com/images/1.jpg -
//you can take this from your move_upload_file
}
?>
<img src="<?PHP echo $imgFile; ?>" />
Useful links How to receive a file via HTTP PUT with PHP
Even for a restful service u can use json or xml to send the image url back. PUT is not a good idea unless u need to send back image data for some reason. May be u should rethink your logic?
The mistakes was:
strlen($image) strlen if wrong, must be filesize and in my url I had www. It's not netion in my post but it was mistake.
More experienced programmer helped me.
r.php to read stream:
$res = file_get_contents("php://input");
$file = fopen('1.txt', "w");
fputs($file, $res);
fclose($file);
var_dump($res);
s.php to get stream and to init r.php
$image = fopen('/var/www/testfiles/1.jpg', "rb");
var_dump($image);
$ch = curl_init();
/* Set cURL options. */
curl_setopt($ch, CURLOPT_URL, "http://url withot www/r.php");
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, $image);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize('/var/www/testfiles/1.jpg'));
/* Execute the PUT and clean up */
$result = curl_exec($ch);
fclose($image); //recommended to close the fileshandler after action
curl_close($ch);
die("OK");
I am using following code to download files from some remote server using php
//some php page parsing code
$url = 'http://www.domain.com/'.$fn;
$path = 'myfolder/'.$fn;
$fp = fopen($path, 'w');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
$data = curl_exec($ch);
curl_close($ch);
fclose($fp);
// some more code
but instead of downloading and saving the file in the directory it is showing the file contents (junk characters as file is zip) directly on the browser only.
I guess it might be an issue with header content, but not know exactly ...
Thanks
I believe you need:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
to make curl_exec() return the data, and:
$data = curl_exec($ch);
fwrite($fp, $data);
to get the file actually written.
As mentioned in http://php.net/manual/en/function.curl-setopt.php :
CURLOPT_RETURNTRANSFER: TRUE to return the transfer as a string of the return value of curl_exec() instead of outputting it out directly.
So you can simply add this line before your curl_exec line:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
and you will have the content in $data variable.
Use the following function that includes error handling.
// Download and save a file with curl
function curl_dl_file($url, $dest, $opts = array())
{
// Open the local file to save. Suppress warning
// upon failure.
$fp = #fopen($dest, 'w+');
if (!$fp)
{
$err_arr = error_get_last();
$error = $err_arr['message'];
return $error;
}
// Set up curl for the download
$ch = curl_init($url);
if (!$ch)
{
$error = curl_error($ch);
fclose($fp);
return $error;
}
$opts[CURLOPT_FILE] = $fp;
// Set up curl options
$failed = !curl_setopt_array($ch, $opts);
if ($failed)
{
$error = curl_error($ch);
curl_close($ch);
fclose($fp);
return $error;
}
// Download the file
$failed = !curl_exec($ch);
if ($failed)
{
$error = curl_error($ch);
curl_close($ch);
fclose($fp);
return $error;
}
// Close the curl handle.
curl_close($ch);
// Flush buffered data to the file
$failed = !fflush($fp);
if ($failed)
{
$err_arr = error_get_last();
$error = $err_arr['message'];
fclose($fp);
return $error;
}
// The file has been written successfully at this point.
// Close the file pointer
$failed = !fclose($fp);
if (!$fp)
{
$err_arr = error_get_last();
$error = $err_arr['message'];
return $error;
}
}