近期搞了一个安卓的客户端,想把它挂到站点上提供下载,整理实现思路如下:
(1).浏览器发送一个请求,请求访问服务器中的某个网页(如:down.php)
(2).运行该文件的时候,必然要把将要被下载的文件读入内存当中,通过fopen()函数完成该动作
(3).从内存当中读取文件,通过fread()函数完成该动作
(4).把读到的内容输出到客户端
需要注意的是,如果文件较大,文件应该是被分成多段返回给客户端的,并不是等文件在服务端全部读取完毕后,一次性返回给客户端,因为这样子会增加服务器的负荷。
所以我们需要在php代码中设置一次读取的字节数,比如我在下面的代码中通过$buffer=1024设置一次读取的字节数,每读取一次,就输出数据(即返回给浏览器)
具体实现如下,我把代码贴出来,代码都做了详细的注释,保证能看明白
public function index() { $file_name="Kl博客.apk"; //用以解决中文不能显示出来的问题 $file_name=iconv("utf-8","gb2312",$file_name); $file_sub_path=$_SERVER['DOCUMENT_ROOT']./admin.php?s=."/Uploads/DownFile/"; $file_path=$file_sub_path.$file_name; //完整的文件路径 //首先要判断给定的文件存在与否 if(!file_exists($file_path)){ echo "来晚了,文件不存在"; } else { $fp=fopen($file_path,"r"); //以只读的方式打开文件 $file_size=filesize($file_path);//得到文件大小 //下载文件需要用到的头 Header("Content-type: application/octet-stream"); //告诉浏览器这是一个文件流格式的文件 Header("Accept-Ranges: bytes"); //告诉客户端浏览器返回的文件大小是按照字节进行计算的 Header("Content-length:".$file_size); //告诉浏览器返回的文件大小 Header("Content-Disposition: attachment; filename=".$file_name); //告诉浏览器文件的名称 $buffer=1024; //设置缓冲区大小 $file_count=0; //读取到的文件大小变量 //向浏览器返回数据 while(!feof($fp) && $file_count<$file_size){ $file_con=fread($fp,$buffer); //读到一个缓冲区文件的大小 $file_count+=$buffer; //累积读到的文件大小 echo $file_con; //直接向浏览器输出 } //echo fread($fp, $file_size);//小文件可以直接一次性读完 fclose($fp); //可以把缓冲区内最后剩余的数据输出到磁盘文件中,并释放文件指针和有关的缓冲区 } }