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 相关文章推荐
基于文本的留言簿
Oct 09 PHP
discuz authcode 经典php加密解密函数解析
Jul 12 PHP
完美实现GIF动画缩略图的php代码
Jan 02 PHP
关于初学PHP时的知识积累总结
Jun 07 PHP
php一些错误处理的方法与技巧总结
Aug 10 PHP
php读取mysql的简单实例
Jan 15 PHP
php转换颜色为其反色的方法
Apr 27 PHP
php中删除、清空session的方式总结
Oct 09 PHP
php使用include 和require引入文件的区别
Feb 16 PHP
PHP中Notice错误常见解决方法
Apr 28 PHP
PHP实现ASCII码与字符串相互转换的方法
Apr 29 PHP
详解no input file specified 三种解决方法
Nov 29 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下正则来匹配dede模板标签的代码
2010/08/21 PHP
完美实现wordpress禁止文章修订和自动保存的方法
2014/11/03 PHP
Yii2简单实现多语言配置的方法
2016/07/23 PHP
PHP实现上传多图即时显示与即时删除的方法
2017/05/09 PHP
用户注册常用javascript代码
2009/08/29 Javascript
jQuery的实现原理的模拟代码 -5 Ajax
2010/08/07 Javascript
Javascript 中 null、NaN和undefined的区别总结
2013/04/10 Javascript
用jQuery实现一些导航条切换,显示隐藏的实例代码
2013/06/08 Javascript
Javascript改变CSS样式(局部和全局)
2013/12/18 Javascript
基于jQuery 实现bootstrapValidator下的全局验证
2015/12/07 Javascript
深入解析桶排序算法及Node.js上JavaScript的代码实现
2016/07/06 Javascript
js使用Replace结合正则替换重复出现的字符串功能示例
2016/12/27 Javascript
利用transition实现文字上下抖动的效果
2017/01/21 Javascript
AngularJS实现动态添加Option的方法
2017/05/17 Javascript
微信小程序搜索组件wxSearch实例详解
2017/06/08 Javascript
新手vue构建单页面应用实例代码
2017/09/18 Javascript
浅谈Angular4中常用管道
2017/09/27 Javascript
Thinkjs3新手入门之添加一个新的页面
2017/12/06 Javascript
Angular 开发学习之Angular CLI的安装使用
2017/12/31 Javascript
微信小程序在地图选择地址并返回经纬度简单示例
2018/12/03 Javascript
可拖拽组件slider.js使用方法详解
2020/12/04 Javascript
详解Django缓存处理中Vary头部的使用
2015/07/24 Python
利用Python获取操作系统信息实例
2016/09/02 Python
python使用tensorflow深度学习识别验证码
2018/04/03 Python
用Python写脚本,实现完全备份和增量备份的示例
2018/04/29 Python
浅谈pycharm下找不到sqlalchemy的问题
2018/12/03 Python
使用HTML5中的contentEditable来将多行文本自动增高
2016/03/01 HTML / CSS
Lancome兰蔻官方旗舰店:来自法国的世界知名美妆品牌
2018/06/14 全球购物
预备党员入党思想汇报
2014/01/04 职场文书
宿舍打麻将检讨书
2014/01/24 职场文书
初一科学教学反思
2014/01/27 职场文书
党员公开承诺书2015
2015/01/21 职场文书
上班旷工检讨书
2015/08/15 职场文书
解决linux下redis数据库overcommit_memory问题
2022/02/24 Redis
【海涛教你打DOTA】黑鸟第一视角解说
2022/04/01 DOTA
MySQL运行报错:“Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre”解决方法
2022/06/14 MySQL