I have a force-download script that produces good results with PDF and plain text, and is semi-OK with ZIP archives (they work in Windows, not in Linux). However, application files and images all fail. These make up the vast majority of the files I must handle. Zipping all downloads, as I've seen suggested on similar topics here, is not an option.
The failing files download to their full size, and are written to disk under the correct name. Attempts to open them result in a error message, which differs between types. Comparing downloaded files to their originals in hexdump, I can see that the script inserts the following characters at the start of each downloaded file:
ef bb bf
The downloaded file then reproduces the original until it stops at its specified size - so the original's last 6 characters are always missing.
Unfortunately I know nothing about how binary files are made up, what these characters might mean, or how/why the script is inserting them.
This is the script as-is:
$file = '94.ppt';
$path = $_SERVER['DOCUMENT_ROOT']."/relative/path/";
$full_path = $path.$file;
if ($fd = fopen ($full_path, "r")) {
$fsize = filesize($full_path);
$path_parts = pathinfo($full_path);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
case "pdf":
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
case "txt":
header("Content-type: text/plain");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
case "jpg":
header("Content-type: image/jpeg");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
case "ppt":
header("Content-Type: application/vnd.ms-powerpoint");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
default;
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
}
header("Content-Transfer-Encoding: binary");
header("Content-length: $fsize");
header("Cache-control: private");
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
exit;
The development system is PHP 5.3.2-1 on Apache 2.2.14 (Ubuntu). The production host is PHP 5.2.9 on Apache 2.0.63 (some type of Linux).
Your PHP script file seems to be encoded in UTF-8 with BOM that is right at the begin of the file before the opening <?php
delimiter. These bytes are sent before your actual output and thus corrupting your data.
You just need to remove it and configure your editor not to use the BOM for UTF-8.
EF BB BF
is the standard UTF-8 byte order mark. Some people have reported that this happens when some of your PHP files that you include in the script are UTF-8 encoded; some versions of PHP react to this by sending out the UTF-8 byte order marker. The link above suggests calling ob_start()
at the beginning of the script and ob_end_clean()
before you start pushing out the contents of your file -- this way the byte order marker gets caught in the output buffer.
Also, you could simply use fpassthru
to pipe your file to the output instead of reading and writing in a loop.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With