我正在为我目前正在处理的一个更大的项目构建一个小的下载模块,遇到了一些问题。虽然它非常适合小文件,但当浏览器(任何浏览器)开始下载较大的文件时,它就像任何页面一样加载,然后在最后几秒钟几乎立即"下载"整个文件(无论大小)。我已经一遍又一遍地浏览了HTTP 1.1标准,并且似乎在遵循它们。立即想到的一个想法是 PHP 何时实际向客户端发送数据。答案应该是脚本运行时 - 我在其他长脚本中使用此原则进行调试。
这是相关的代码段(当然还有更多,但这是标头和输出实际发送的地方:
header("Content-Type: application/force-download");
header("Content-length: $size");
header('Content-Disposition: attachment; filename="'.$fileData['name'].'"');
for ($i=0; $i<$size; $i+=$step)
{
$content = fread($file, $step);
if ($content === false)
$content = "";
echo $content;
}
die();
有什么想法吗?我有一种感觉,这是一个明显的问题,我只是盯着这个块这么久就看不出来了。
提前感谢!
在这里试试这个,如果传递的文件是目录或未找到,此函数将返回 false。 它还将从文件名中删除空格,以免中断下载。 也可以通过更改1024
来限制下载速度,它将处理超过 2GB 的文件。
<?php
function download($file){
if (file_exists($file)) {
if(is_dir($file)){return false;}
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.str_ireplace(' ','_',basename($file)).'"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: '.sprintf("%u", filesize($file)));
@ob_clean();
$handle = fopen($file, "rb");
$chunksize=(sprintf("%u", (filesize($file))/1024));
set_time_limit(0);
while (!feof($handle)) {
echo fgets($handle, $chunksize);
flush();
}
fclose($handle);
die;
}else{return false;}
return;
}
?>
只需使用工具,停止重新发明轮子。 pecl_http已经存在了一段时间了。
<?php
http_send_content_disposition("document.pdf", true);
http_send_content_type("application/pdf");
http_throttle(0.1, 2048);
http_send_file("../report.pdf");
?>
此代码示例快速,健壮,并为您提供多种功能奖励:
- 带宽限制
- 缓存和标头管理
- 部分和断点续传下载