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判断搜索引擎蜘蛛并自动记忆到文件的代码
Feb 04 PHP
php判断变量类型常用方法
Apr 24 PHP
关于svn冲突的解决方法
Jun 21 PHP
CodeIgniter框架数据库事务处理的设计缺陷和解决方案
Jul 25 PHP
php批量删除超链接的实现方法
Oct 19 PHP
使用PHP实现生成HTML静态页面
Nov 18 PHP
Symfony生成二维码的方法
Feb 04 PHP
PHP的Yii框架中Model模型的学习教程
Mar 29 PHP
PHP中Restful api 错误提示返回值实现思路
Apr 12 PHP
PHP随机数 C扩展随机数
May 04 PHP
PHP中set_include_path()函数相关用法分析
Jul 18 PHP
PHP进阶学习之垃圾回收机制详解
Jun 18 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
漫威DC即将合作联动,而双方早已经秘密开始
2020/04/09 欧美动漫
用Simple Excel导出xls实现方法
2012/12/06 PHP
PHP根据两点间的经纬度计算距离
2014/10/31 PHP
PHP文件读取功能的应用实例
2015/05/08 PHP
PHP实现带重试功能的curl连接示例
2016/07/28 PHP
javascript中interval与setTimeOut的区别示例介绍
2014/03/14 Javascript
JavaScript实现生成GUID(全局统一标识符)
2014/09/05 Javascript
jquery+html5烂漫爱心表白动画代码分享
2015/08/24 Javascript
WEB前端开发都应知道的jquery小技巧及jquery三个简写
2015/11/15 Javascript
js省市联动效果完整实例代码
2015/12/09 Javascript
javascript生成img标签的3种实现方法(对象、方法、html)
2015/12/25 Javascript
Express + Node.js实现登录拦截器的实例代码
2017/07/01 Javascript
Electron autoUpdater实现Windows安装包自动更新的方法
2018/12/24 Javascript
微信小程序缓存过期时间的使用详情
2019/05/12 Javascript
前后端常见的几种鉴权方式(小结)
2019/08/04 Javascript
Vue微信公众号网页分享的示例代码
2020/05/28 Javascript
利用js实现简易红绿灯
2020/10/15 Javascript
[46:04]Liquid vs VP Supermajor决赛 BO 第四场 6.10
2018/07/05 DOTA
Python抓取手机号归属地信息示例代码
2016/11/28 Python
PyQT实现多窗口切换
2018/04/20 Python
Django框架模板介绍
2019/01/15 Python
python画图把时间作为横坐标的方法
2019/07/07 Python
Python Django框架url反向解析实现动态生成对应的url链接示例
2019/10/18 Python
python matplotlib imshow热图坐标替换/映射实例
2020/03/14 Python
IE9对HTML5中部分属性不支持的原因分析
2014/10/15 HTML / CSS
HTML5 Canvas实现烟花绽放特效
2016/03/02 HTML / CSS
如何避免常见的6种HTML5错误用法
2017/11/06 HTML / CSS
SQL Server的固定数据库角色都有哪些?对应的服务器权限有哪些?
2013/05/18 面试题
2013年入党人员的自我鉴定
2013/10/25 职场文书
运动会800米加油稿
2014/02/22 职场文书
一年级小学生评语大全
2014/12/25 职场文书
2015年小学二年级班主任工作总结
2015/05/21 职场文书
情人节单身感言
2015/08/03 职场文书
导游词之无锡东林书院
2019/12/11 职场文书
Python selenium的这三种等待方式一定要会!
2021/06/10 Python
自从在 IDEA 中用了热部署神器 JRebel 之后,开发效率提升了 10(真棒)
2021/06/26 Java/Android