Using Header as download link in PHP - php

So I am having this problem wit my download link. Basically my previous way of creating download link is to just have a form button with method='link' and the action to be the link to the file. This works for firefox and others but not safari. For some reason, when the user tries to download the file (excel file) from safari, it would just show bunch of ascii characters on the browser (I guess its trying to read it using the browser?). Well, I was looking for another solution and it seems like using header is the way to do it. So now I am tryng to create a form button with method='post' and action='download.php' where there is a hidden field with the link to the file. It looks like this
function showDownloadWithHeader($link){
echo "<form action='download.php' method='post' >";
echo "<input class='downloadButton' type='submit' value='Download Report'>";
echo "<input type='hidden' name='filename' value='$link'>";
echo "</form>";
}
And inside the download.php I would just want the user to be asked to download the file.
<?php
if($_POST['filename'] == '' || empty($_POST['filename'])){
exit;
}
$filename = $_POST['filename']; //the file is 2 folder down. e.g. data/stack/bla.xlsx
$file = $filename;
$extension = end(explode('.', $filename));
error_reporting(E_ALL);
ini_set("display_errors",1);
// echo $filename;
// echo "<br/>";
// echo $extension;
// echo filesize($filename);
// echo "<br/>";
switch($extension){
case 'xls':
$mimeType = 'application/vnd.ms-excel';
break;
case 'xlsx':
$mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
break;
}
// echo $mimeType;
header('Content-Description: File Transfer');
header('Content-Type: ' . $mimeType);
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
    flush();
readfile($filename);
exit;
?>
I saw this solution on php.net under readfile() function but it doesnt seem to be working for me. I am doing this on localhost.

Something like this works fine.
header("Pragma: public", true);
header("Expires: 0"); // set expiration time
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment; filename=".basename($file));
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($file));
die(file_get_contents($file));

If I understand you correctly the script is working as expected, i.e if a browser recognizes mime type:
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
Then it SHOWS it in browser (whether or not it displays correctly is something else)
Since you want to FORCE it to download INSTEAD OF showing in browser use the mime type:
'application/octet-stream'
This should work in all browsers and force the download instead of display in browser.

Related

dataurl to image for download in php

I'm creating image using canvas and using following script,
function getImage() {
var canvas1 = document.getElementById("images");
if (canvas1.getContext) {
var ctx = canvas1.getContext("2d");
var myImage = canvas1.toDataURL("image/jpg");
}
$('<form action="download.php" method="POST">' +
'<input type="hidden" name="aid" value="' + myImage + '">' +
'</form>').submit();
}
And in my Download.php file is,
<?php $img = $_POST['aid'];
echo "<img src=".$img.">";
?>
it showing image correctly. But i wanna give download button with jpg format or pdf format.
How i can use?
I used base64_decode(); method. But i cant solve.
Help me...
Thanks for all. but I got answer using,
file_put_contents();
But thing, i dont know how to use. Finally i got it from this Answer.
Answer is,
$data = 'data:image/png;base64,AAAFBfj42Pj4';
list($type, $data) = explode(';', $data);
list(, $data) = explode(',', $data);
$data = base64_decode($data);
file_put_contents('/tmp/image.png', $data);
But still i'm waiting for download button with option of image/pdf format.
Try this:
PHP echo'ed image with link
<?php
$img = $_POST['aid'];
echo "";
?>
download_image.php
<?php
$img = "myimage.jpg";
// fix for IE catching or PHP bug issue
header("Pragma: public");
header("Expires: 0"); // set expiration time
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
// browser must download file from server instead of cache
// force download dialog
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
// use the Content-Disposition header to supply a recommended filename and
// force the browser to display the save dialog.
header("Content-Disposition: attachment; filename=".basename($img).";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($img));
readfile("$img");
exit();
?>

Adding download option to images

I have a PHP script that is working fine for displaying all my images in a directy that I upload to. I wand to make a little download button so someone can click the button and download the image. I am making this for my company so people can download our logos.
<?php
// Find all files in that folder
$files = glob('grips/*');
// Do a natural case insensitive sort, usually 1.jpg and 10.jpg would come next to each other with a regular sort
natcasesort($files);
// Display images
foreach($files as $file) {
echo '<img src="' . $file . '" />';
}
?>
I figue I could just make a button and call the href of $file but that would just link to the file and show the image. I am not sure to have it auto download. Any help would be great.
Just add some headers in a download.php file so you can then read the file in like this:
Make sure you sanitize your data coming to the file, you don't want people to be able to download your php files.
<?php
// Find all files in that folder
$files = glob('grips/*');
// Do a natural case insensitive sort, usually 1.jpg and 10.jpg would come next to each other with a regular sort
natcasesort($files);
// Display images
foreach($files as $file) {
echo '<img src="' . $file . '" /><br />Download Image';
}
?>
download.php
$filename = base64_decode($_GET["file"]);
// Data sanitization goes here
if(!getimagesize($filename) || !is_file($filename)){
// Not an image, or file doesn't exist. Redirect user
header("Location: /back_to_images.php");
exit;
}
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment; filename=".basename($filename).";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
readfile($filename);

php how to serve file but NOT for download

The code below forces browser to fire a prompt to save/open file (https://kb.wisc.edu/images/group27/13334/open-prompt.PNG) even if it's a image or pdf file.
I want images to be opened as usual, pdf files to be displayed in browser. And of course other files that are not supported by browser like zip, rar, doc, xls etc will fire a save file dialog.
Edit:
My intention is not to block client to save the file of course they can save it that's impossible. I want to serve let say images as PHP files like main.php?file=randomcode (which is stored in database) but not as /images/somefilename.jpg . My code forces client to download it but I want to display it.
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"" . $filename . "." . $fileinfo["file_extension"] . "\";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($file));
$fp = fopen($file, "r");
if ($fp) {
while (!feof($fp)) {
$cur_data = fread($fp, 1024);
echo $cur_data;
}
} else {
echo "Error: Could not the read file.";
}
Ultimately it's up to the client what to do with the content it receives. One thing you can do is get rid of the Content-disposition header:
header("Content-Disposition: attachment; filename=\"" . $filename . "." . $fileinfo["file_extension"] . "\";");
(Or at least get rid of it conditionally, depending on specific factors about the file.) What this header does is tell the client that the content being returned is a "file" (you even provide a suggested name for the file) and should be treated as such. HTTP has no native concept of "files" so this header exists specifically to identify something as a "file."
By not supplying that header, you're not suggesting to the client that the content is a file. The client may still infer that it's a file and treat it as such (which you can't control), but from your end all you'd be doing is returning the content itself.
Well, apparently you know the file extension so you could do:
if(in_array($fileinfo["file_extension"], array('jpg', 'png', 'gif')) {
// set header for viewing the image
$mime_type = $fileinfo["file_extension"];
if($mime_type == 'jpg') {
$mime_type = 'jpeg';
}
header('Content-Type: image/' . $mime_type);
}
else {
// set headers for downloading the file
}
if the content type is set to octate stream then it will defenetly transfer the file means user will force download it. you have to set content type accordingly to open it in browser
for example if type is image then
header("Content-Type: image/jpg");
header("Content-Type: image/png");
etc.
and if its image or pdf then remove Content-Disposition: header

Joomla component + forcedownload

i have coded a component (Gallery). And i want to intergrate forcedownload for all items.
But will not work :(, just getting corrupted files. I have tried to use exact same code and run it outside of joomla and its works fine. I have created a template thats totaly empty just
have but its not help.
My (com_component/views/forcedownload/tmpl/default.php)
<?php
if(!isset($_GET["id"]) || empty($this->item)) {
echo "Invalid request";
die();
}
$path = "images/randomtest/catid".$this->item->cat_id."/";
$filename = $path.$this->item->filename;
$file = $this->item->filename;
if(!file_exists($filename)) {
echo "Error: File not found";
die();
}
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$file");
header("Content-Type: Content-type: application/octet-stream");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
readfile($filename);
?>
The first thing is: Are you using $_GET['format'] = raw? If not in your controller do
if(!isset($_GET["format"]) || $_GET["format"]!='raw') {
$this->setRedirect( JURI::current(). '?format=raw' );
return false;
}
also in your header you are declared content type as: application/octet-stream, are you sure you want this?
also here:
$path = "images/randomtest/catid".$this->item->cat_id."/";
you need, whole SYSTEM PATH not only local one, try using:
$path = JPATH_SITE."/images/randomtest/catid".$this->item->cat_id."/";

Files not having any content in after a header() download

I'm trying to create a download so that a user clicks on "down" it downloads a certain file from their account to their computer, I'm currently using this:
header('Content-Disposition: attachment; filename=' . basename("users/$username/$file_folder/$file_name"));
header("Content-Type:" .$file_type);
header("Content-Description: File Transfer");
header("Cache-control: private");
header("Connection: close");
header("Content-Length: ".$file_size);
The problem is, the file is downloading, but it's just empty, there is no content in the file
The code before this is just an if() and a while loop with database records.
Thanks in advance.
You are missing something like below: (unless the file is very large, in which case you would chunk it out)
$filename = 'path/to/file/file_name.txt';
echo file_get_contents($filename);
Alternatively you could populate a variable with the data you want put out into the file and simple echo it out like so:
$data = "begin\n";
$data .= "first line\n";
$data .= "another line\n";
$data .= "last line";
echo $data;
The content would be put out there AFTER your headers. Hope this helps.
The file is empty, because you never output the file. These header calls are just the header, you still need a body for a file to be correctly downloaded. You can use file_get_contents to echo the file contents.
header('Content-Disposition: attachment; filename=' . basename("users/$username/$file_folder/$file_name"));
header("Content-Type:" .$file_type);
header("Content-Description: File Transfer");
header("Cache-control: private");
header("Connection: close");
header("Content-Length: ".$file_size);
// echo the file, this will make the download work
echo file_get_contents("users/$username/$file_folder/$file_name");
after you send the headers you need to actually push out the file content...
see this
http://php.net/manual/en/function.file-put-contents.php

Categories