用php下载文件不全,最大只有1.9多M

php output_buffering ob_start ob_end_flush

php 中用readfile下载文件的问题:

1. output_buffering=off,无权改变;

2. 由于要用到head()函数,所以会出错;
header(‘Content-Type: application-x/force-download’);
header(‘Content-Disposition: attachment; filename=”‘ . basename($filename) .’”‘);
header(‘Content-Length: ‘ . filesize($filename)); //加了这句,下载到的文件有错,打不开!
header(‘Cache-Control: no-cache, must-revalidate’);
header(‘Pragma: no-cache’);

3. 用 ob_start 和 ob_end_flush 解决;

4. 产生的新问题,下载的文件不完整,大于2M的文件,只下到1.9M就完成了,导致文件无法打开;

5. 增加 php.ini 的 memory_limit 到 96M,也一样;

6. 不使用 ob_start and ob_end_flush,也不用 head(),改用以下几句:
echo ‘<meta http-equiv=”content-type” content=”application-x/force-download” />’;
echo ‘<meta http-equiv=”Content-Disposition” content=”attachment; filename=\”.basename($filename).’\’” />’;
echo ‘<meta http-equiv=”Cache-Control” content=”no-cache, must-revalidate” />’;
echo ‘<meta http-equiv=”Pragma” content=”no-cache” />’;

没用,无法下载,文件在浏览器打开了。
一定在服务器先发送才行。

7. 试另一个方法,也无果:
$fp = fopen($filename, ‘rb’);
return fpassthru($fp);

8. 总是会有这样的问题啊,下载到1.9M多的时候,在IE下,就停一下,最后也是下载不完整。
有意思的是,这些代码是在另一同事安装的WAMP环境下运行的,有这样的问题,而在我维护的另一个LAMP环境下,则没有这些问题。

9. 最后,还是在PHP手册参考了以下代码搞定:

if (($f = fopen($filename, ‘rb’)) === false) exit;

// Push file
while (!feof($f)) {
echo fread($f, (1*(1024*1024)));
flush();
@ob_flush();
}

// Close file
fclose($f);

10. 全部的代码如下:

<?php
//ob_start();
//ini_set(‘memory_limit’,’96′);

function forceDownload($filename)
{
//echo $filename;
//$filename = substr($filename,1,100);
$filename = ‘./’.str_replace(‘../’,’./’,$filename);

//if (stristr($filename,”.php”))
//if (!eregi(“.pdf|.xls|.jpg|.jpeg”,basename($filename)))
if (eregi(“.php|.inc|.ini|.aspx”,basename($filename)))
{
echo “Don’t do that!”;
return false;
}

if (false == file_exists($filename))
{
echo “File not exists!”;
return false;
}

// http headers
//application/octet-stream
//header(“Pragma: public”);
header(“Expires: Thu, 19 Nov 1981 08:52:00 GMT”);
header(“Cache-Control: must-revalidate, post-check=0, pre-check=0″);
header(“Cache-Control: no-store, no-cache, must-revalidate”);
//header(“Cache-Control: private”);
header(“Content-Transfer-Encoding: binary”);

header(‘Content-Type: application-x/force-download’);
header(‘Content-Disposition: attachment; filename=”‘ . basename($filename) .’”‘);
header(‘Content-Length: ‘ .filesize($filename)); //加了这句,下载到的文件有错,打不开!

// for IE6
if (false === strpos($_SERVER['HTTP_USER_AGENT'], ‘MSIE 6′))
{
header(‘Cache-Control: no-cache, must-revalidate’);
}
header(‘Pragma: no-cache’);
// read file content and output
//return readfile($filename);

// $fp = fopen($filename, ‘rb’);
// return fpassthru($fp);

// Open file
if (($f = fopen($filename, ‘rb’)) === false) exit;

// Push file
while (!feof($f)) {
echo fread($f, (1*(1024*1024)));
flush();
@ob_flush();
}

// Close file
fclose($f);

}
$file = $_GET['file'];
forceDownload($file);
//ob_end_flush();
?>

This entry was posted in Program and tagged , . Bookmark the permalink.

One Response to 用php下载文件不全,最大只有1.9多M

  1. flyingnn says:

    IE6下,有点问题,把这两句注解后OK:
    header(“Cache-Control: must-revalidate, post-check=0, pre-check=0″);
    header(“Cache-Control: no-store, no-cache, must-revalidate”);

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>