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编程语言开发动态WAP页面
Oct 09 PHP
在php MYSQL中插入当前时间
Apr 06 PHP
php中将汉字转换成拼音的函数代码
Sep 08 PHP
使用dump函数,给php加断点测试
Jun 25 PHP
php 使用GD库为页面增加水印示例代码
Mar 24 PHP
PHP快速按行读取CSV大文件的封装类分享(也适用于其它超大文本文件)
Apr 10 PHP
php 伪造ip以及url来路信息方法汇总
Nov 25 PHP
PHP基于单例模式实现的mysql类
Jan 09 PHP
php简单随机字符串生成方法示例
Apr 19 PHP
PHP mongodb操作类定义与用法示例【适合mongodb2.x和mongodb3.x】
Jun 16 PHP
浅谈PHP封装CURL
Mar 06 PHP
Thinkphp5.0 框架的请求方式与响应方式分析
Oct 14 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
ADODB结合SMARTY使用~超级强
2006/11/25 PHP
解析PHP的session过期设置
2013/06/29 PHP
PHP实现批量上传单个文件
2015/12/29 PHP
PHP+MySql+jQuery实现的&quot;顶&quot;和&quot;踩&quot;投票功能
2016/05/21 PHP
CI框架无限级分类+递归的实现代码
2016/11/01 PHP
PHP设计模式之工厂模式(Factory Pattern)的讲解
2019/03/21 PHP
PHP实现批量修改文件名的方法示例
2019/09/18 PHP
document.body.scrollTop 值总为0的解决方法 比较常见的标准问题
2009/11/30 Javascript
jQuery插件jQuery-JSONP开发ajax调用使用注意事项
2013/11/22 Javascript
jQuery截取指定长度字符串代码
2014/08/21 Javascript
简介JavaScript中的setHours()方法的使用
2015/06/11 Javascript
判断js的Array和Object的实现方法
2016/08/29 Javascript
react.js 翻页插件实例代码
2017/01/19 Javascript
JavaScript之浏览器对象_动力节点Java学院整理
2017/07/03 Javascript
使用vue for时为什么要key【推荐】
2019/07/11 Javascript
python内置函数:lambda、map、filter简单介绍
2017/11/16 Python
Python内建模块struct实例详解
2018/02/02 Python
python计算两个地址之间的距离方法
2018/06/09 Python
numpy返回array中元素的index方法
2018/06/27 Python
tensorflow更改变量的值实例
2018/07/30 Python
Python设计模式之策略模式实例详解
2019/01/21 Python
从0开始的Python学习016异常
2019/04/08 Python
Python面向对象之类和实例用法分析
2019/06/08 Python
对pytorch中的梯度更新方法详解
2019/08/20 Python
Python中Unittest框架的具体使用
2019/08/27 Python
实现ECharts双Y轴左右刻度线一致的例子
2020/05/16 Python
keras的backend 设置 tensorflow,theano操作
2020/06/30 Python
如何用Anaconda搭建虚拟环境并创建Django项目
2020/08/02 Python
Foot Locker加拿大官网:美国知名运动产品零售商
2019/07/21 全球购物
银行实习生自我鉴定范文
2013/09/19 职场文书
2014年基层党组织公开承诺书
2014/03/29 职场文书
奶茶店创业计划书
2014/08/14 职场文书
奉献爱心演讲稿
2014/09/04 职场文书
党委领导班子整改方案
2014/09/30 职场文书
暑期家教宣传单
2015/07/14 职场文书
创业计划书之电动车企业
2019/10/11 职场文书