让PHP更快的提供文件下载的代码


Posted in PHP onJune 13, 2012

但是, 这样做, 就没办法做一些统计, 权限检查, 等等的工作. 于是, 很多时候, 我们采用让PHP来做转发, 为用户提供文件下载.

<?php 
$file = "/tmp/dummy.tar.gz"; 
header("Content-type: application/octet-stream"); 
header('Content-Disposition: attachment; filename="' . basename($file) . '"'); 
header("Content-Length: ". filesize($file)); 
readfile($file);

但是这个有一个问题, 就是如果文件是中文名的话, 有的用户可能下载后的文件名是乱码.

于是, 我们做一下修改(参考: :

<?php 
$file = "/tmp/中文名.tar.gz"; 
$filename = basename($file); 
header("Content-type: application/octet-stream"); 
//处理中文文件名 
$ua = $_SERVER["HTTP_USER_AGENT"]; 
$encoded_filename = urlencode($filename); 
$encoded_filename = str_replace("+", "%20", $encoded_filename); 
if (preg_match("/MSIE/", $ua)) { 
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"'); 
} else if (preg_match("/Firefox/", $ua)) { 
header("Content-Disposition: attachment; filename*=\"utf8''" . $filename . '"'); 
} else { 
header('Content-Disposition: attachment; filename="' . $filename . '"'); 
} 
header('Content-Disposition: attachment; filename="' . $filename . '"'); 
header("Content-Length: ". filesize($file)); 
readfile($file);

恩, 现在看起来好多了, 不过还有一个问题, 那就是readfile, 虽然PHP的readfile尝试实现的尽量高效, 不占用PHP本身的内存, 但是实际上它还是需要采用MMAP(如果支持), 或者是一个固定的buffer去循环读取文件, 直接输出.

输出的时候, 如果是Apache + PHP mod, 那么还需要发送到Apache的输出缓冲区. 最后才发送给用户. 而对于Nginx + fpm如果他们分开部署的话, 那还会带来额外的网络IO.

那么, 能不能不经过PHP这层, 直接让Webserver直接把文件发送给用户呢?

今天, 我看到了一个有意思的文章: How I PHP: X-SendFile.

我们可以使用Apache的module mod_xsendfile, 让Apache直接发送这个文件给用户:

<?php 
$file = "/tmp/中文名.tar.gz"; 
$filename = basename($file); 
header("Content-type: application/octet-stream"); 
//处理中文文件名 
$ua = $_SERVER["HTTP_USER_AGENT"]; 
$encoded_filename = urlencode($filename); 
$encoded_filename = str_replace("+", "%20", $encoded_filename); 
if (preg_match("/MSIE/", $ua)) { 
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"'); 
} else if (preg_match("/Firefox/", $ua)) { 
header("Content-Disposition: attachment; filename*=\"utf8''" . $filename . '"'); 
} else { 
header('Content-Disposition: attachment; filename="' . $filename . '"'); 
} 
header('Content-Disposition: attachment; filename="' . basename($file) . '"'); 
//让Xsendfile发送文件 
header("X-Sendfile: $file");

X-Sendfile头将被Apache处理, 并且把响应的文件直接发送给Client.
Lighttpd和Nginx也有类似的模块, 大家有兴趣的可以去找找看
PHP 相关文章推荐
安装APACHE
Jan 15 PHP
php模板中出现空行解决方法
Mar 08 PHP
php空间不支持socket但支持curl时recaptcha的用法
Nov 07 PHP
解析PHP汉字转换拼音的类
Jun 18 PHP
php全角字符转换为半角函数
Feb 07 PHP
单台服务器的PHP进程之间实现共享内存的方法
Jun 13 PHP
ThinkPHP入库出现两次反斜线转义及数据库类转义的解决方法
Nov 04 PHP
PHP获取数组最后一个值的2种方法
Jan 21 PHP
php根据生日计算年龄的方法
Jul 13 PHP
php实现过滤字符串中的中文和数字实例
Jul 29 PHP
php实现评论回复删除功能
May 23 PHP
php的对象传值与引用传值代码实例讲解
Feb 26 PHP
深入理解PHP之数组(遍历顺序)  Laruence原创
Jun 13 #PHP
header中Content-Disposition的作用与使用方法
Jun 13 #PHP
php文件打包 下载之使用PHP自带的ZipArchive压缩文件并下载打包好的文件
Jun 13 #PHP
Php中文件下载功能实现超详细流程分析
Jun 13 #PHP
php异常处理技术,顶级异常处理器
Jun 13 #PHP
PHP的异常处理类Exception的使用及说明
Jun 13 #PHP
PHP抽象类 介绍
Jun 13 #PHP
You might like
php生成html文件方法总结
2014/12/01 PHP
Ubuntu下安装PHP的mongodb扩展操作命令
2015/07/04 PHP
php批量删除超链接的实现方法
2015/10/19 PHP
使用composer安装使用thinkphp6.0框架问题【视频教程】
2019/10/01 PHP
PHP连续签到功能实现方法详解
2019/12/04 PHP
javascript 主动派发事件总结
2011/08/09 Javascript
浅析js设置控件的readonly与enabled属性问题
2013/12/25 Javascript
javascript中replace( )方法的使用
2015/04/24 Javascript
JS封装cookie操作函数实例(设置、读取、删除)
2015/11/17 Javascript
JS使用eval()动态创建变量的方法
2016/06/03 Javascript
window.close(); 关闭浏览器窗口js代码的总结介绍
2016/07/14 Javascript
AngularJS实现树形结构(ztree)菜单示例代码
2016/09/18 Javascript
JavaScript仿百度图片浏览效果
2016/11/23 Javascript
jsp 自动编译机制详细介绍
2016/12/01 Javascript
nodejs利用http模块实现银行卡所属银行查询和骚扰电话验证示例
2016/12/30 NodeJs
RequireJS 依赖关系的实例(推荐)
2017/01/21 Javascript
JS非空验证及邮箱验证的实例
2017/08/11 Javascript
详解在React.js中使用PureComponent的重要性和使用方式
2018/07/10 Javascript
解决vue项目刷新后,导航菜单高亮显示的位置不对问题
2019/11/01 Javascript
jQuery实现移动端扭蛋机抽奖
2020/11/08 jQuery
Python自动扫雷实现方法
2015/07/25 Python
Python3实现的画图及加载图片动画效果示例
2018/01/19 Python
python序列化与数据持久化实例详解
2019/12/20 Python
pytorch方法测试——激活函数(ReLU)详解
2020/01/15 Python
Python xlrd模块导入过程及常用操作
2020/06/10 Python
Python Selenium模块安装使用教程详解
2020/07/09 Python
CSS3 网页下拉菜单代码解释 中文翻译
2010/02/27 HTML / CSS
英国打印机墨水和碳粉商店:Printerinks
2017/06/30 全球购物
新驾驶员个人自我评价
2014/01/03 职场文书
无故旷工检讨书
2014/01/26 职场文书
大学校务公开实施方案
2014/03/31 职场文书
中秋寄语大全
2014/04/11 职场文书
政府法律服务方案
2014/06/14 职场文书
2015年党风廉政建设责任书
2015/01/29 职场文书
三峡大坝导游词
2015/01/31 职场文书
2015年社区反邪教工作总结
2015/10/14 职场文书