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中使用Oracle数据库(3)
Oct 09 PHP
php批量删除数据
Jan 18 PHP
PHP+SQL 注入攻击的技术实现以及预防办法
Dec 29 PHP
ThinkPHP3.1之D方法实例详解
Jun 20 PHP
PHP抓取及分析网页的方法详解
Apr 26 PHP
既简单又安全的PHP验证码 附调用方法
Jun 02 PHP
PHP 微信扫码支付源代码(推荐)
Nov 03 PHP
php计算多个集合的笛卡尔积实例详解
Feb 16 PHP
自写的利用PDO对mysql数据库增删改查操作类
Feb 19 PHP
TP(thinkPHP)框架多层控制器和多级控制器的使用示例
Jun 13 PHP
laravel获取不到session的三种解决办法【推荐】
Sep 16 PHP
php设计模式之正面模式实例分析【星际争霸游戏案例】
Mar 24 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
截获网站title标签之家内容的例子
2006/10/09 PHP
ThinkPHP php 框架学习笔记
2009/10/30 PHP
php中使用Curl、socket、file_get_contents三种方法POST提交数据
2011/08/12 PHP
php导入模块文件分享
2015/03/17 PHP
php面试中关于面向对象的相关问题
2019/02/13 PHP
PHP的介绍以及优势详细分析
2019/09/05 PHP
javascript 多级checkbox选择效果
2009/08/20 Javascript
jQuery的三种$()
2009/12/30 Javascript
JavaScript toFixed() 方法
2010/04/15 Javascript
javascript文件中引用依赖的js文件的方法
2014/03/17 Javascript
javascript实现左右控制无缝滚动
2014/12/31 Javascript
PHPMyAdmin导入时提示文件大小超出PHP限制的解决方法
2015/03/30 Javascript
基于jQuery实现动态搜索显示功能
2016/05/05 Javascript
详解VUE的状态控制与延时加载刷新
2017/03/27 Javascript
VueJs使用Amaze ui调整列表和内容页面
2017/11/30 Javascript
three.js实现3D模型展示的示例代码
2017/12/31 Javascript
Layui给数据表格动态添加一行并跳转到添加行所在页的方法
2018/08/20 Javascript
微信小程序实现手势滑动卡片效果
2019/08/26 Javascript
python元组操作实例解析
2014/09/23 Python
利用python操作SQLite数据库及文件操作详解
2017/09/22 Python
Flask数据库迁移简单介绍
2017/10/24 Python
Python决策树和随机森林算法实例详解
2018/01/30 Python
python读取目录下所有的jpg文件,并显示第一张图片的示例
2019/06/13 Python
pycharm设置鼠标悬停查看方法设置
2019/07/29 Python
详解pyinstaller selenium python3 chrome打包问题
2019/10/18 Python
pytorch 自定义卷积核进行卷积操作方式
2019/12/30 Python
Chantelle仙黛尔内衣美国官网:法国第一品牌内衣
2018/07/26 全球购物
什么是SCM(软件配置管理)
2014/08/16 面试题
自我评价范文
2013/12/22 职场文书
四个太阳教学反思
2014/02/01 职场文书
中国好声音广告词
2014/03/18 职场文书
互联网创业计划书写作技巧攻略
2014/03/23 职场文书
村抢险救灾方案
2014/05/09 职场文书
学习焦裕禄同志为人民服务思想汇报
2014/09/10 职场文书
关于springboot配置druid数据源不生效问题(踩坑记)
2021/09/25 Java/Android
JS前端轻量fabric.js系列物体基类
2022/08/05 Javascript