php文件下载进度显示原理
我们在文件下载时经常需要知道文件的下载进度,那么利用php
获取文件的下载进度,不能在一般的windows
平台集成的环境下,这是因为window
的文件权限控制机制不同于linux
。导致不能讲真正的文件大小赋予Content-Length
。这样,浏览器在请求了服务器之后,在Response Headers
里不能获取文件的大小而呈现出动态更新文件下载进度的效果 ,在linux
环境下,我们至少需要赋予文件004
其他人可读的权限,并将文件大小赋值给Content-Length
,这样就能实现预先设想的效果。
实现代码demo
$file_name="1.jpg";
$file_dir = "./";
$filesize=filesize($file_dir.$file_name);//获取文件的大小
if (!file_exists($file_dir . $file_name)) {
echo "nofile";
exit;
} else {
$file = fopen($file_dir . $file_name,"r");//只读方式打开文件
Header("Content-Length: ".$filesize);//获取文件下载进度的关键,需要知道总的文件大小
//Header("Content-Type: application/octet-stream");//文件类型,二进制码流
Header("Accept-Ranges: bytes");
Header("Content-Disposition: attachment; filename=".$file_name);
flush();//将header头先由apache冲出,交给浏览器
echo fread($file,$filesize);//读取文件流
fclose($file);
exit;
}
注意点
在使用flush()
函数时,其会立刻由服务器冲出位于该语句之前的内容。若Content-Length
是于其之前赋值,那么浏览器Response-Headers
中的内容便是其设置的内容,头部先被冲出,文件的加载过程可能会较长。若不flush()
冲出,Response-Headers
中的Content-Length
虽然有被设置一次,但是最终输出的是页面所呈现的输出值。
一般情况下ResponseHeaders Content-Length
遵循获取最短的规则,如果页面输出小于所设定的值,则取页面输出值的长度。如果大于等于Content-Length
所设定的值,则取Content-Length
所设之值,同时页面输出会被截为相应的数值。