Php中文件下载功能实现超详细流程分析


Posted in PHP onJune 13, 2012

客户端从服务端下载文件的流程分析:

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

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

流程图:
Php中文件下载功能实现超详细流程分析

<?php 
header("Content-type:text/html;charset=utf-8"); 
// $file_name="cookie.jpg"; 
$file_name="圣诞狂欢.jpg"; 
//用以解决中文不能显示出来的问题 
$file_name=iconv("utf-8","gb2312",$file_name); 
$file_sub_path=$_SERVER['DOCUMENT_ROOT']."marcofly/phpstudy/down/down/"; 
$file_path=$file_sub_path.$file_name; 
//首先要判断给定的文件存在与否 
if(!file_exists($file_path)){ 
echo "没有该文件文件"; 
return ; 
} 
$fp=fopen($file_path,"r"); 
$file_size=filesize($file_path); 
//下载文件需要用到的头 
Header("Content-type: application/octet-stream"); 
Header("Accept-Ranges: bytes"); 
Header("Accept-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; 
} 
fclose($fp); 
?>

几点注意事项:

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)可以把缓冲区内最后剩余的数据输出到磁盘文件中,并释放文件指针和有关的缓冲区

PHP 相关文章推荐
BBS(php &amp; mysql)完整版(二)
Oct 09 PHP
PHP编程中字符串处理的5个技巧小结
Nov 13 PHP
php字符串截取中文截取2,单字节截取模式
Dec 10 PHP
PHP设计模式之迭代器模式的深入解析
Jun 13 PHP
使用php测试硬盘写入速度示例
Jan 27 PHP
PHP内核探索:变量存储与类型使用说明
Jan 30 PHP
php实现的双向队列类实例
Sep 24 PHP
thinkPHP5实现的查询数据库并返回json数据实例
Oct 23 PHP
CentOS7.0下安装PHP5.6.30服务的教程详解
Sep 29 PHP
利用PHP如何统计Nginx日志的User Agent数据
Mar 06 PHP
PHP5.6.8连接SQL Server 2008 R2数据库常用技巧分析总结
May 06 PHP
解决laravel 出现ajax请求419(unknown status)的问题
Sep 03 PHP
php异常处理技术,顶级异常处理器
Jun 13 #PHP
PHP的异常处理类Exception的使用及说明
Jun 13 #PHP
PHP抽象类 介绍
Jun 13 #PHP
MySQL 日期时间函数常用总结
Jun 12 #PHP
PHP简洁函数(PHP简单明了函数语法)
Jun 10 #PHP
php数字游戏 计算24算法
Jun 10 #PHP
细谈php中SQL注入攻击与XSS攻击
Jun 10 #PHP
You might like
天津市收音机工业发展史
2021/03/04 无线电
php 生成唯一id的几种解决方法
2013/03/08 PHP
php常用ODBC函数集(详细)
2013/06/24 PHP
php多用户读写文件冲突的解决办法
2013/11/06 PHP
几个优化WordPress中JavaScript加载体验的插件介绍
2015/12/17 PHP
常见的5个PHP编码小陋习以及优化实例讲解
2021/02/27 PHP
json 实例详细说明教程
2009/10/31 Javascript
JavaScript对象、属性、事件手册集合方便查询
2010/07/04 Javascript
jQuery中的.bind()、.live()和.delegate()之间区别分析
2011/06/08 Javascript
JS判断不同分辨率调用不同的CSS样式文件实现思路及测试代码
2013/01/23 Javascript
在Iframe中获取父窗口中表单的值(示例代码)
2013/11/22 Javascript
jquery map方法使用示例
2014/04/23 Javascript
jQuery基于扩展实现的倒计时效果
2016/05/14 Javascript
微信小程序新增的拖动组件movable-view使用教程
2017/05/20 Javascript
React-Native中props具体使用详解
2017/09/04 Javascript
vue axios 在页面切换时中断请求方法 ajax
2018/03/05 Javascript
VSCode中如何利用d.ts文件进行js智能提示
2018/04/13 Javascript
微信小程序左滑动显示菜单功能的实现
2018/06/14 Javascript
JS 图片压缩原理与实现方法详解
2020/04/29 Javascript
js实现轮播图特效
2020/05/28 Javascript
python之yield表达式学习
2014/09/02 Python
深入解析Python中的上下文管理器
2016/06/28 Python
python 实现tar文件压缩解压的实例详解
2017/08/20 Python
特征脸(Eigenface)理论基础之PCA主成分分析法
2018/03/13 Python
python pytest进阶之xunit fixture详解
2019/06/27 Python
pandas 时间格式转换的实现
2019/07/06 Python
python怎么调用自己的函数
2020/07/01 Python
canvas实现俄罗斯方块的方法示例
2018/12/13 HTML / CSS
使用HTML5 Canvas API绘制弧线的教程
2016/03/22 HTML / CSS
Laravel中Kafka的使用详解
2021/03/24 PHP
信息工程学院毕业生推荐信
2013/11/05 职场文书
幼儿园父亲节活动方案
2014/03/11 职场文书
小学生心理健康活动总结
2015/05/08 职场文书
2016秋季校长开学典礼致辞
2015/11/26 职场文书
研究生毕业登记表的自我鉴定范文
2019/07/15 职场文书
每日六道java新手入门面试题,通往自由的道路
2021/06/30 Java/Android