设为首页 收藏本站
查看: 585|回复: 0

[经验分享] Php如何实现下载功能超详细流程分析

[复制链接]

尚未签到

发表于 2015-8-24 10:53:08 | 显示全部楼层 |阅读模式
  客户端从服务端下载文件的流程分析:


  • 浏览器发送一个请求,请求访问服务器中的某个网页(如:down.php),该网页的代码如下。
  • 服务器接受到该请求以后,马上运行该down.php文件
  • 运行该文件的时候,必然要把将要被下载的文件读入内存当中(这里是圣诞狂欢.jpg这张图片),这里通过fopen()函数完成该动作
  注意:任何有关从服务器下载的文件操作,必然需要先在服务端将文件读入内存当中                                                              


  • 现在文件已经在内存当中了,这是需要从内存当中读取文件,通过fread()函数完成该动作
  • 需要注意的是,如果文件较大,文件应该是被分成多段返回给客户端的,并不是等文件在服务端全部读取完毕后,一次性返回给客户端,因为这样子会增加服务器的负荷。
  所以我们需要在php代码中设置一次读取的字节数,比如我在下面的代码中通过$buffer=1024设置一次读取的字节数,每读取一次,就输出数据(即返回给浏览器)
  流程图:
DSC0000.png
  



1 代码:
2 <?php
3     header("Content-type:text/html;charset=utf-8");
4 //    $file_name="cookie.jpg";
5     $file_name="圣诞狂欢.jpg";
6     //用以解决中文不能显示出来的问题
7     $file_name=iconv("utf-8","gb2312",$file_name);
8     $file_sub_path=$_SERVER['DOCUMENT_ROOT']."marcofly/phpstudy/down/down/";
9     $file_path=$file_sub_path.$file_name;
10     //首先要判断给定的文件存在与否
11     if(!file_exists($file_path)){
12         echo "没有该文件文件";
13         return ;
14     }
15     $fp=fopen($file_path,"r");
16     $file_size=filesize($file_path);
17     //下载文件需要用到的头
18     Header("Content-type: application/octet-stream");
19     Header("Accept-Ranges: bytes");
20     Header("Accept-Length:".$file_size);
21     Header("Content-Disposition: attachment; filename=".$file_name);
22     $buffer=1024;
23     $file_count=0;
24     //向浏览器返回数据
25     while(!feof($fp) && $file_count<$file_size){
26         $file_con=fread($fp,$buffer);
27         $file_count+=$buffer;
28         echo $file_con;
29     }
30 fclose($fp);
31 ?>
  几点注意事项:


  • header("Content-type:text/html;charset=utf-8")的作用:在服务器响应浏览器的请求时,告诉浏览器以编码格式为UTF-8的编码显示该内容
  • 关于file_exists()函数不支持中文路径的问题:因为php函数比较早,不支持中文,所以如果被下载的文件名是中文的话,需要对其进行字符编码转换,否则file_exists()函数不能识别,可以使用iconv()函数进行编码转换
  • $file_sub_path() 我使用的是绝对路径,执行效率要比相对路径高
  • Header("Content-type: application/octet-stream")的作用:通过这句代码客户端浏览器就能知道服务端返回的文件形式
  • Header("Accept-Ranges: bytes")的作用:告诉客户端浏览器返回的文件大小是按照字节进行计算的
  • Header("Accept-Length:".$file_size)的作用:告诉浏览器返回的文件大小
  • Header("Content-Disposition: attachment; filename=".$file_name)的作用:告诉浏览器返回的文件的名称
  • 以上四个Header()是必需的
  • fclose($fp)可以把缓冲区内最后剩余的数据输出到磁盘文件中,并释放文件指针和有关的缓冲区
  新浪微博:http://weibo.com/cstmr

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-103375-1-1.html 上篇帖子: Android上传图片(PHP服务器) 下篇帖子: 如何让我们的PHP在Jexus中跑起来
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表