Re: Forced File Downloads

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Don wrote:
> I've been having my forced downloads sometimes finish prematurely using
> readfile(). I'm downloading a Windows .exe file.
> 
> I've read several posts that have suggested the substitution of a fread/feof
> loop to write out the download in smaller chunks. I tried using a function
> (readfile_chunked) I found in the user comments on php.net.
> 
> But for some odd reason, every time the downloaded file is one byte larger
> than the original file, and it's not being recognized as a valid Windows 
> file.


does the end of your download script look like this?:

?>

by which I mean does it actually resemble one of the following strings:

$end = "?>
";
$end = "?> ";


is there a space or newline AFTER the last closing php tag?

avoid this PITA type of bug and never ever add a closing php tag
*if* it's the last thing in the file .. the php engine will see that it's reached
EOF and consider that as a closing tag as far as trying to parse any code
goes.

> 
> I'm using PHP 4.4.4 on a shared Linux server running Apache.
> IE and FireFox both exhibit the problem on the Windows end. I'm
> using WinXP SP2.
> 
> I've listed relevant snippets below. $file_name is the fully qualified
> path to the (.exe) file.
> 
> Any ideas?
> #=============================
> 
> # Download the File
> 
> #=============================
> 
> header("Pragma: public");
> 
> header("Expires: 0");
> 
> header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
> 
> header("Cache-Control: private", false);
> 
> header("Content-Description: File Transfer");
> 
> header("Content-Type: application/octet-stream");
> 
> header("Accept-Ranges: bytes");
> 
> header("Content-Disposition: attachment; filename=" . $file_name . ";");
> 
> header("Content-Transfer-Encoding: binary");
> 
> header("Content-Length: " . @filesize($file_path));
> 
> header ("Connection: close");
> 
> @ignore_user_abort();
> 
> @set_time_limit(0);
> 
> // @readfile($file_path);
> 
> readfile_chunked($file_path, FALSE);
> 
> exit();
> 
> ......
> 
> function readfile_chunked($filename, $retbytes = true) {
> 
>  $chunksize = 8 * 1024; // how many bytes per chunk
> 
>  $buffer = '';
> 
>  $cnt = 0;
> 
>  $handle = fopen($filename, 'rb');
> 
>  if ($handle === false) {
> 
>  return false;
> 
>  }
> 
>  while (!feof($handle)) {
> 
>  $buffer = fread($handle, $chunksize);
> 
>  echo $buffer;
> 
>  ob_flush();
> 
>  flush();
> 
>  if ($retbytes) {
> 
>  $cnt += strlen($buffer);
> 
>  }
> 
>  }
> 
>  $status = fclose($handle);
> 
>  if ($retbytes && $status) {
> 
>  return $cnt; // return num. bytes delivered like readfile() does.
> 
>  }
> 
>  return $status;
> 
> }
> 

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux