I have a script which automatically downloads a file. It works perfectly to download the file, but the problem is that 50% or more of the time, it downloads a corrupt file.
Usually deleting and downloading again works, but not always.
How can I make this download 100% of the time perfectly always, not corrupted? The file size changes depending on the file being downloaded.
<?php
// Automatically Start File Download
if (isset($_GET['filename'])):
$filename = $_GET['filename'];
$domain = "http://www.domain.com";
$filepath = "/addons/downloads/websites/";
//BUILD THE FILE INFORMATION
$file = $domain . $filepath . $filename;
// echo $filepath . $filename;
// echo $file;
//CREATE/OUTPUT THE HEADER
if (file_exists("/home/unrealde/public_html/ebook/domain.com/".$filepath . $filename)):
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
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($file);
else:
$errorMsg = "<b>Download Error: File $filename Doesnt Exist!</b> <br />Please Contact <a href='mailto:support@domain.com'>support@domain.com</a>";
endif;
echo $errorMsg;
else:
// don't download any file
endif;
?>
Try adding error_reporting(0); at the beginning of the script. Just for fun. If you check php.net for readfile, others have reported that this helps.
Can't you just tar/gzip/zip the contents and provide a tar/gzip/zip file for download instead ?
Smaller file transfer increase chances of success over http transfer,
and more importantly, you can provide checksum for user to verify against
My hunch is that something in your program is outputting some data other than the file itself.
Have you looked at the corrupt file in a binary editor and compared it with a non-corrupt version? What you'll find is that either at the beginning or the end of the file, you have some unexpected data, and this is what is corrupting the file.
If you look that file this way, it may become very obvious what the problem is. For example, you may have the file, followed by an error message, in which case maybe your line
echo $errorMsg;
is the culprit.Alternatively you may have some blank space. This could also be the same error message, or it could be that your PHP tags have blank lines above or below them, which are being printed.
My first suggestion would be, since the program is effectively finished when the file is output, to put an explicit
die;
function immediately after thereadfile();
line. This will categorically prevent any further spurious data being output once the file has been sent.That won't help if the bad data is being sent before the
readfile();
, but it does rule out half the possible problems in one swoop.