PHP download script corrupts the file - php

what could be a problem of that, file int the server is good, but after I press download it get corrupted...
<?php
if (isset($_POST['submit'])) {
header('Content-type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
header('Content-Disposition: attachment; filename="ataskaita.docx"');
readfile('../generavimui/ataskaita.docx');
}
?>

Look into the file using notepad or a hex editor. There probably is a PHP error message in there.
Possible reasons include
The file you are looking for doesn't exist
$_POST['submit'] is not set

try ereasing the output buffer before reading the file
if (isset($_POST['submit'])) {
header('Content-type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
header('Content-Disposition: attachment; filename="ataskaita.docx"');
ob_clean();
flush();
readfile('../generavimui/ataskaita.docx');
}

I had the same problem that you are having, except I had some additional problems, such as trailing source code being included in the downloaded file.
To fix it, replace your code with this:
header('Content-Description: File Transfer');
header('Content-type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
header('Content-Disposition: attachment; filename="ataskaita.docx"');
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));
Source Site
Hope this helps

Related

PHP script downloads the php file itself instead of the file given

I already asked this question, but not correctly, and I didn't know, that I can't execute a html page and start a download on the same page, but now I know. The main problem actually still remains, I can't get the CSV file to download, it always get the PHP self. The code is executed. I didn't find any information about CSV in the php.ini. I created the file directly before the download (in another page), so it's impossible, that the it doesn't exist.
<?php
if(empty($_POST['checkbox_put_it_in_CSV_too'])!=1){
$file=fopen('created_files/Rankrohad_P_2021-04-01.csv','w');
$filename='created_files/Rankrohad_P_2021-04-01.csv';
foreach($rankrohad as $line){
fputcsv($file,$line,"|","'");
}
fclose($file);
$fsize=filesize($filename);
if(file_exists($filename)){
header('Content-Description: File Transfer');
header('Content-Type: application/csv');
header('Content_Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: no-cache');
header('Content-Length: '.$fsize);
readfile($filename);
exit;
}
}
?>
The problem is with your headers. Try this:
if(file_exists($filename)){
$fsize=filesize($filename);
header('Content-Description: File Transfer');
header('Content-Type: application/csv');
header("Content-Disposition: attachment; filename=\"$filename\"");
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: no-cache');
header('Content-Length: '.$fsize);
readfile($filename);
exit;
}
At Content-Disposition header I escaped the filename and I placed filesize function in IF.

Big files download through php function readfile not working

I have a piece of code that works well on many servers.
It is used to download a file through the readfile php function.
But in one particular server it does not work for files bigger than 25mb.
Here is the code :
$sysfile = '/var/www/html/myfile';
if(file_exists($sysfile)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="mytitle"');
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($sysfile));
ob_clean();
flush();
readfile($sysfile);
exit();
When I try to download a file lower than 25mb there is no problem, when the file is bigger, the file downloaded is 0 bytes.
I've tried with the function read() and file_get_contents but the problem still present.
My php version is 5.5.3, memory limit is set to 80MB.
Error reporting is on but there is no error displayed even in log file.
Here is the complete solution thanks to the answer of witzawitz:
I needed to use ob_end_flush() and fread();
<?php
$sysfile = '/var/www/html/myfile';
if(file_exists($sysfile)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="mytitle"');
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($sysfile));
ob_clean();
ob_end_flush();
$handle = fopen($sysfile, "rb");
while (!feof($handle)) {
echo fread($handle, 1000);
}
}
?>
I've the same problem recently. I've experimented with different headers and other.
The solution that works for me.
header("Content-Disposition: attachment; filename=export.zip");
header("Content-Length: " . filesize($file));
ob_clean();
ob_end_flush();
readfile($file);
So try to change flush to ob_end_flush.

Download file program using php on unix box

I have created a beginner program to forcefully download file from unix box to windows through browser, it is not throwing any error but shows nothing on browser just a blank page.
PHP version- 5.2.13
Apache-2.0
Unix Box- HP-UX 11.11 (old version latest is 11.31)
local PC- windows XP Prof.
Browser- IE 7, Mozilla.
Below is my code (this code resides on unix box):
<?php
ob_start();
$file = '/opt/hpws/apache/htdocs/barn/file2';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream;charset=utf-8');
header('Content-Disposition: attachment; filename=$file');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>
This line had quotation marks missing:
header('Content-Disposition: attachment; filename=$file');
and in trying to use that line of code, the browser would prompt to save the file as $file.
The line of code should read as:
header('Content-Disposition: attachment; filename="'.basename($file).'"');
The following (tested with a binary file) with file inside the same folder as executed code.
NOTE: You could use header("Content-Type: application/text"); if it's an ASCII file.
<?php
ob_start();
$file = 'file.zip';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream;charset=utf-8');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>
Okay, let's add some checks and debugging.
<?php
$file = '/opt/hpws/apache/htdocs/barn/file2';
if (!file_exists($file)) {
die("The file does not exist");
}
if (!is_file($file)) {
die("Not a file"); // Worry about symlinks later
}
if (!is_readable($file)) {
die("The file is not readable");
}
die("DEBUG: Okay, will send the file -- remove this line and retry");
$name = basename($file); // Or anything else
header('Content-Type: application/octet-stream');
header("Content-Disposition: attachment; filename=\"{$name}\"");
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit();
?>
If this does not work, it should at least tell you why. Also, on the first run, the one when it will still not download the file but only tell you that it will, check that the page does not contain anything else except that one line. Otherwise, you're setting yourself up for a fall; if not this once, as soon as you have to send a file larger than your output buffers, or too many files for your system memory.

php - Filename of file when using firefox to download

I see this tutorial to make download file but I have a problem
Here is my example
$file_url = "D:/my file name.doc"
header('Content-Type: text/json; charset=UTF-8;');
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file_url)."");
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_url));
ob_clean();
flush();
readfile($file_url);
Everything's well in ie or chrome. But when I using firefox to download file. The file download has my is the file name? How to fix that thanks
header('Content-Disposition: attachment; filename="' .basename($file_url).'"');
First of all you are missing ; on the end of the first line.
I think the problem is in filename with spaces.
Try to use readfile(urlencode($file_url)); instead of readfile($file_url);
You should quote filename.
header('Content-Disposition: attachment; filename="' . basename($file_url) . '"');
EDIT: It was as selected answer just with typo in it. Now I fixed it.

Download xlsx file using php

I need make xlsx file download from my site (but not from directly open file url like this: http://site.com/file.xlsx )
So, this is php code
$file = "somefile.xlsx";
header('Content-Description: File Transfer');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
file is downloaded, his extension is .xlsx, but when trying open this file in ms excel, file not opened and I got error : excel cannot open the file.xlsx because the file format or file extension is not valid
Tell please, why this happened? where I am wrong?
After many years, I got same problem, and after searching, I got here again ))
This is solution, that worked for me:
$file = "somefile.xlsx";
// define file $mime type here
ob_end_clean(); // this is solution
header('Content-Description: File Transfer');
header('Content-Type: ' . $mime);
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file) . "\"");
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
readfile($file);
You must be using this code in middle of some other file.
The problem with headers is they need to be set first on a page. They will not work if you have even 1 single space echoing before them. So you need to ob_clean() [clean the buffer] before you are setting headers
Try
ob_clean();
flush();
$file = "somefile.xlsx";
header('Content-Description: File Transfer');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
Remove:
ob_clean();
flush();
Add at the end of code:
exit();
The issue is that flush() will also throw in your *.xlsx file content some garbage it has in it and that will corupt your file, even if you use ob_clean();
For a better understanding go to php.net and read the difference between flush(), ob_flush() and find that you didn't even need them in the first case. Therefore you won't need the ob_clean() too.
This works for me:
header('Content-Description: File Transfer');
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header("Content-Disposition: attachment; filename=\"".basename($fileLocation)."\"");
header("Content-Transfer-Encoding: binary");
header("Expires: 0");
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header('Content-Length: ' . filesize($fileLocation)); //Remove
ob_clean();
flush();
readfile($fileLocation);

Categories