php force download shows garbage on screen - php

I am trying to download a zip file from /tmp folder in Ubuntu. However when I run the Php code it shows garbage text on the browser instead of showing a download box. I tried with a simple text file and instead of showing me a download dialog box it printed its contents on the browser. Why this force-download isn't working. Below is the code.
if (file_exists($dir.$filename)) {
header("Content-type: application/force-download");
header("Content-Transfer-Encoding: Binary");
header("Content-length: ".filesize($dir.$filename));
header('Content-disposition: attachment; filename='.basename($dir.$filename));
readfile($dir.$filename);
exit(0);
}
`

Well, given any browser a MIME type "application/force-download" the browser won't know what to do with it.
Since it is a zip file, the MIME type should be "application/octet-stream" or "application/zip".
if (file_exists($dir . $filename)) {
header("Content-type: application/zip");
header("Content-Transfer-Encoding: Binary");
header("Content-length: " . filesize($dir . $filename));
header('Content-disposition: attachment; filename=' . basename($dir . $filename));
readfile($dir . $filename);
exit(0);
}

You cannot read whole file into memory. Change your readfile($_REQUEST['file']); into:
$handle=fopen($_REQUEST['file'], 'rb');
while (!feof($handle))
{
echo fread($handle, 8192);
flush();
}
fclose($handle);
This will read 8kb of file, then push it to the client, and so on... It will consume not much memory (as it's not reading whole file at once).
Also when forcing download always use application/octet-stream this will ensure correct sending of binary files.

Related

docx file is corrupted after download from server using php

I'm trying to download a a word document (.docx) from the server using php. Unfortunately the document I get is corrupted. I can open the document with word, but I get these annoying messages (File is corrupted etc.). Here is my code:
$file = "documents/".$_POST["id_form"]."_document.docx";
$filename = $_POST["id_form"]."_document.docx";
header("Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document");
header("Content-Disposition: attachment; filename=".$filename);
readfile($file);
Thanks for your help!
UPDATE SOLUTION
I got the solution. I had to put ob_end_clean(); before the header and a exit; after readfile($file). Now it works fine.
Here is the working code:
$file = "documents/".$_POST["id_form"]."_document.docx";
$filename = $_POST["id_form"]."_document.docx";
ob_end_clean();
header("Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document");
header("Content-Disposition: attachment; filename=".$filename);
readfile($file);
exit;

Downloading a file in php doesn't work for pdf but works for text files

I am trying to force download a file in my php program under a new name (new_name). I am changing the file name but keeping the extension the same as roginal file. This is part of my code:
$original_filename = "attachments/20180315.log";
$new_filename = "new_name." . pathinfo($original_filename, PATHINFO_EXTENSION);
header("Content-Length: " . filesize($original_filename));
header("Content-Transfer-Encoding: binary");
header('Content-Disposition: attachment; filename="' . $new_filename . '"');
header('Pragma: no-cache');
readfile($original_filename);
exit;
My download is working fine when I am downloading a text file (i.e. in example above 20180315.log is a text file). When I try to do the same with a binary file (such as pdf) I am getting an empty new_name.pdf.
Any suggestion?
I have always found the exact headers required to be a bit messy and dependent on the browser, there are a lot of options, and you will see a lot of variations posted, so i suggest the following, but you may need to just test a number of combinations until you get it right, and i suggest making sure you test it on as many browsers as you can.
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . $new_filename . "\"");
readfile($original_filename);

Php File Size header()

$file_name = $_GET['name'];
$file_url = $_GET['file-url'] . $file_name;
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"".$file_name."\"");
readfile($file_url);
exit;
I'm using this code to download files in my site fetching from another web servers.
It works if my url looks like this:-
https://www.example.com/file_download.php?name=video_song.mp4&file-url=http://www.googlevideo.com/video/play/221589
So, it starts downloading by fetching the file from http://www.googlevideo.com/video/play/221589 in my site. Now, though it downloads the file correctly, it does allow the downloader to see the actual size of the file. So, downloaders having problems with it (e.g. Time Remaining, Download Percentage etc.).
So what header should I use to solve this thing? Please explain it by coding.
You may try this:
header("Content-Length: " . $filesize);

Content-Disposition downloading wrong file

I am trying to download a file. I am using IE11. I have tried several methods to do this. Currently I am trying to use the header with Content-Disposition method. I have tried to do this a few different ways according to other answers people have given. And it does download. But instead of downloading the file I point it to, it downloads the file it is written in. So if I tell it to download example.txt in my test.php file. It will only download test.php.
These are the methods I have tried:
This one is written in test.html:
<?php
$filename = "example.txt"
header('Content-Type: text/plain');
header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
?>
I've also tried making it a button:
BUTTON
Where download.php is:
<?php
$file = $_GET['file'];
header('Content-type: audio/mpeg');
header('Content-Disposition: attachment; filename="'.$file.'"');
?>
I tried this:
<?php
header('Content-Type: application/download');
header('Content-Disposition: attachment; filename="example.txt"');
header("Content-Length: " . filesize("example.txt"));
$fp = fopen("example.txt", "r");
fpassthru($fp);
fclose($fp);
?>
And this:
header("Content-Disposition: attachment; filename=\"" . basename($File) . "\"");
header("Content-Type: application/force-download");
header("Content-Length: " . filesize($File));
header("Connection: close");
There are many more slight variations and mix and matching that I have tried. All have the same problem that the .html or .php file downloads rather than example.txt. Does anyone know why this would happen? Is something not supported in IE11? I do not think it is a syntax error simply because most of these I copied from other answers online. I have tried with example.txt existing and not existing, in this folder and other folders.
EDIT: So it turns out that these all work, I was just using them wrong. I had been trying to make isolated files to run this code so I could test it without interference from the rest of the functions on my website, but this left the php files without the resources they needed to actually run properly. When I put the code into the actual files on the website it worked perfectly. smh
Try this :
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . filesize($File));
header('Content-Disposition: attachment; filename=' . basename($File));
readfile($File);
exit;

Download Excel File from Server has been corrupted - PHP

I have a problem about downloading Excel file from server.
the excel file was already saved on the server and I downloaded it using the code below.
if(file_exists($reportPath)){
//content type
header('Content-type: application/vnd.ms-excel');
//open/save dialog box
header('Content-Disposition: attachment; filename='.$dirFile[count($dirFile)-1]);
//read from server and write to buffer
readfile($reportPath);
}
But the downloaded file was corrupted.
I'm pretty sure that the file saved on the server is not corrupted since I have get it manually from the server to my local desktop.
Meaning, the data has been corrupted on the fly.
Please help, thank you, I'm using PHP
Can you try these headers?
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="'.$dirFile[count($dirFile)-1].'"');
header('Cache-Control: max-age=0');
And see if it's working... Cheers!
Download script should be separate file. Actually you should not print out anything in this script
//Add below to download the text file created
$filename = $file; //name of the file
$filepath = $file; //location of the file. I have put $file since your file is create on the same folder where this script is
header("Cache-control: private");
header("Content-type: application/force-download");
header("Content-transfer-encoding: binary\n");
header("Content-disposition: attachment; filename=\"$filename\"");
header("Content-Length: ".filesize($filepath));
readfile($filepath);
exit;
$fileName = "data.xls";
$object_writer = PHPExcel_IOFactory::createWriter($object, 'Excel5');
ob_end_clean();
header("Content-Type: application/download");
header('Content-Disposition: attachment;filename=' . $fileName);
$object_writer->save('php://output');
use ob_end_clean() to clear the output buffer.
This is what fixed my issue :
adding ob_end_clean funct after the save.
adding exit at the end of the script.

Categories