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 相关文章推荐
一个自定义位数的php多用户计数器代码
Mar 11 PHP
php正则校验用户名介绍
Jul 19 PHP
PHP curl模拟浏览器采集阿里巴巴的实现代码
Apr 20 PHP
PHP 异步执行方法,模拟多线程的应用分析
Jun 03 PHP
PHP实现手机号码中间四位用星号(*)隐藏的自定义函数分享
Sep 27 PHP
javascript some()函数用法详解
Nov 13 PHP
Yii2使用自带的UploadedFile实现的文件上传
Jun 20 PHP
mysql查找删除重复数据并只保留一条实例详解
Sep 24 PHP
PHP内存缓存功能memcached示例
Oct 19 PHP
PHP读取Excel类文件
May 15 PHP
yii框架结合charjs统计上一年与当前年数据的方法示例
Apr 04 PHP
PHP设计模式(九)外观模式Facade实例详解【结构型】
May 02 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
PHP中使用CURL伪造来路抓取页面或文件
2011/05/04 PHP
php实现的微信红包算法分析(非官方)
2015/09/25 PHP
Yii框架 session 数据库存储操作方法示例
2019/11/18 PHP
教您去掉ie网页加载进度条的方法
2010/12/09 Javascript
js open() 与showModalDialog()方法使用介绍
2013/09/10 Javascript
ajax请求get与post的区别总结
2013/11/04 Javascript
javascript中JSON对象与JSON字符串相互转换实例
2015/07/11 Javascript
让你一句话理解闭包(简单易懂)
2016/06/03 Javascript
最好用的Bootstrap fileinput.js文件上传组件
2016/12/12 Javascript
在iframe中使bootstrap的模态框在父页面弹出问题
2017/08/07 Javascript
原生JS实现的轮播图功能详解
2018/08/06 Javascript
解决vue打包报错Unexpected token: punc的问题
2020/10/24 Javascript
使用Python编写Linux系统守护进程实例
2015/02/03 Python
用生成器来改写直接返回列表的函数方法
2017/05/25 Python
python2和python3的输入和输出区别介绍
2018/11/20 Python
python实现图片识别汽车功能
2018/11/30 Python
python中对数据进行各种排序的方法
2019/07/02 Python
pycharm新建一个python工程步骤
2019/07/16 Python
Win10下python 2.7与python 3.7双环境安装教程图解
2019/10/12 Python
python框架django项目部署相关知识详解
2019/11/04 Python
关于Numpy数据类型对象(dtype)使用详解
2019/11/27 Python
python如何判断IP地址合法性
2020/04/05 Python
python脚本监控logstash进程并邮件告警实例
2020/04/28 Python
在pycharm中文件取消用 pytest模式打开的操作
2020/09/01 Python
Python爬虫简单运用爬取代理IP的实现
2020/12/01 Python
pandas map(),apply(),applymap()区别解析
2021/02/24 Python
Python 求向量的余弦值操作
2021/03/04 Python
学生党员思想汇报
2013/12/28 职场文书
书法比赛获奖感言
2014/02/10 职场文书
经典广告词大全
2014/03/14 职场文书
黄金搭档广告词
2014/03/21 职场文书
环保建议书600字
2014/05/14 职场文书
2014年班组工作总结
2014/11/20 职场文书
售后服务质量承诺书
2015/04/29 职场文书
Python-OpenCV实现图像缺陷检测的实例
2021/06/11 Python
JPA 通过Specification如何实现复杂查询
2021/11/23 Java/Android