php文件下载进度控制总结

Posted by Alex Kinhoom on December 7, 2017

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所设之值,同时页面输出会被截为相应的数值。