note 99406 added to function.readfile

From: 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

« previous php.notes (#171719) next »