note 99406 added to function.readfile
| From: | chrisbloom7 at gmail dot com | Date: | Mon, 16 Aug 2010 03:32:51 +0000 |
| Subject: | note 99406 added to function.readfile | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-171719@lists.php.net to get a copy of this message | ||
This seems to be one of those areas of programming where there is no hard and fast rule as to what
works. I tried countless permutations of the tricks I found on this page and elsewhere on the web
until I finally found something that works. This might be overkill, but it works so I'm leaving
it as is. So far this was tested on Mac/Apache and Win32/Apache servers, using Firefox, Safari and
Chrome clients. I've tested this with files up to 151MB and as small as a few Kb. As usual,
YMMV.
<?php
$realpath = "/some/absolute/path.exe";
$mtime = ($mtime = filemtime($realpath)) ? $mtime : gmtime();
$size = intval(sprintf("%u", filesize($realpath)));
// Maybe the problem is we are running into PHPs own memory limit, so:
if (intval($size + 1) > return_bytes(ini_get('memory_limit')) && intval($size *
1.5) <= 1073741824) { //Not higher than 1GB
ini_set('memory_limit', intval($size * 1.5));
}
// Maybe the problem is Apache is trying to compress the output, so:
@apache_setenv('no-gzip', 1);
@ini_set('zlib.output_compression', 0);
// Maybe the client doesn't know what to do with the output so send a bunch of these headers:
header("Content-type: application/force-download");
header('Content-Type: application/octet-stream');
if (strstr($_SERVER["HTTP_USER_AGENT"], "MSIE") != false) {
header("Content-Disposition: attachment; filename=" .
urlencode(basename($F['FILE']['file_path'])) . ';
modification-date="' . date('r', $mtime) . '";');
} else {
header("Content-Disposition: attachment; filename=\"" .
basename($F['FILE']['file_path']) . '"; modification-date="'
. date('r', $mtime) . '";');
}
// Set the length so the browser can set the download timers
header("Content-Length: " . $size);
// If it's a large file we don't want the script to timeout, so:
set_time_limit(300);
// If it's a large file, readfile might not be able to do it in one go, so:
$chunksize = 1 * (1024 * 1024); // how many bytes per chunk
if ($size > $chunksize) {
$handle = fopen($realpath, 'rb');
$buffer = '';
while (!feof($handle)) {
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();
}
fclose($handle);
} else {
readfile($realpath);
}
// Exit successfully. We could just let the script exit
// normally at the bottom of the page, but then blank lines
// after the close of the script code would potentially cause
// problems after the file download.
exit;
?>
----
Server IP: 64.71.164.2
Probable Submitter: 96.228.226.71
----
Manual Page -- http://www.php.net/manual/en/function.readfile.php
Edit -- https://master.php.net/note/edit/99406
Del: integrated -- https://master.php.net/note/delete/99406/integrated
Del: useless -- https://master.php.net/note/delete/99406/useless
Del: bad code -- https://master.php.net/note/delete/99406/bad+code
Del: spam -- https://master.php.net/note/delete/99406/spam
Del: non-english -- https://master.php.net/note/delete/99406/non-english
Del: in docs -- https://master.php.net/note/delete/99406/in+docs
Del: other reasons-- https://master.php.net/note/delete/99406
Reject -- https://master.php.net/note/reject/99406
Search -- https://master.php.net/manage/user-notes.php