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 20 PHP
关于shopex同步ucenter的redirect问题,导致script不运行
Apr 10 PHP
php while循环得到循环次数
Oct 26 PHP
PHP移动文件指针ftell()、fseek()、rewind()函数总结
Nov 18 PHP
ThinkPHP中redirect用法分析
Dec 05 PHP
php根据一个给定范围和步进生成数组的方法
Jun 19 PHP
PHP随机数 C扩展随机数
May 04 PHP
php实现连接access数据库并转txt写入的方法
Feb 08 PHP
PHP实现超简单的SSL加密解密、验证及签名的方法示例
Aug 28 PHP
PDO::errorCode讲解
Jan 28 PHP
PHP+iframe模拟Ajax上传文件功能示例
Jul 02 PHP
PHP使用redis位图bitMap 实现签到功能
Oct 08 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环境下利用session防止页面重复刷新的具体实现
2014/01/09 PHP
php中出现空白页的原因及解决方法汇总
2014/07/08 PHP
关于laravel模板中生成URL的几种模式总结
2019/10/18 PHP
javascript 打印内容方法小结
2009/11/04 Javascript
jQuery版Tab标签切换
2011/03/16 Javascript
jQuery中jqGrid分页实现代码
2011/11/04 Javascript
分享精心挑选的12款优秀jQuery Ajax分页插件和教程
2012/08/09 Javascript
js禁止document element对象选中文本实现代码
2013/03/21 Javascript
javascript中的if语句使用介绍
2013/11/20 Javascript
详解Wondows下Node.js使用MongoDB的环境配置
2016/03/01 Javascript
jquery ajax双击div可直接修改div中的内容
2016/03/04 Javascript
js从外部获取图片的实现方法
2016/08/05 Javascript
微信小程序 SocketIO 实例讲解
2016/10/13 Javascript
详解vue嵌套路由-params传递参数
2017/05/23 Javascript
详解基于 Nuxt 的 Vue.js 服务端渲染实践
2017/10/24 Javascript
JavaScript实现简单动态进度条效果
2018/04/06 Javascript
vue基础之事件简写、事件对象、冒泡、默认行为、键盘事件实例分析
2019/03/11 Javascript
Node.js Domain 模块实例详解
2020/03/18 Javascript
Node.js API详解之 tty功能与用法实例分析
2020/04/27 Javascript
Python获取单个程序CPU使用情况趋势图
2015/03/10 Python
使用requests库制作Python爬虫
2018/03/25 Python
解决tensorflow1.x版本加载saver.restore目录报错的问题
2018/07/26 Python
Python人脸识别第三方库face_recognition接口说明文档
2019/05/03 Python
Python代码使用 Pyftpdlib实现FTP服务器功能
2019/07/22 Python
基于python实现把json数据转换成Excel表格
2020/05/07 Python
keras中模型训练class_weight,sample_weight区别说明
2020/05/23 Python
浅谈python量化 双均线策略(金叉死叉)
2020/06/03 Python
详解python定时简单爬取网页新闻存入数据库并发送邮件
2020/11/27 Python
python 模拟登录B站的示例代码
2020/12/15 Python
编写类String的构造函数、析构函数和赋值函数
2012/05/29 面试题
市优秀教师事迹材料
2014/02/05 职场文书
2014年物业管理工作总结
2014/11/21 职场文书
实习工作表现评语
2014/12/31 职场文书
乱世佳人观后感
2015/06/08 职场文书
P站美图推荐——变身女主角特辑
2022/03/20 日漫
详解Anyscript开发指南绕过typescript类型检查
2022/09/23 Javascript