在PHP中使用X-SendFile头让文件下载更快
2023-06-13 09:15:27 时间
一般来说,我们可以通过直接让URL指向一个位于DocumentRoot下面的文件,来引导用户下载文件.
但是,这样做,就没办法做一些统计,权限检查,等等的工作.于是,很多时候,我们采用让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=rawurlencode($filename);
if(preg_match("/MSIE/",$ua)){
header("Content-Disposition:attachment;filename="".$encoded_filename.""");
}elseif(preg_match("/Firefox/",$ua)){
header("Content-Disposition:attachment;filename*=\"utf8""".$filename.""");
}else{
header("Content-Disposition:attachment;filename="".$filename.""");
}
header("Content-Length:".filesize($file));
readfile($file);
恩,现在看起来好多了,不过还有一个问题,那就是readfile,虽然PHP的readfile尝试实现的尽量高效,不占用PHP本身的内存,但是实际上它还是需要采用MMAP(如果支持),或者是一个固定的buffer去循环读取文件,直接输出.
输出的时候,如果是Apache+PHPmod,那么还需要发送到Apache的输出缓冲区.最后才发送给用户.而对于Nginx+fpm如果他们分开部署的话,那还会带来额外的网络IO.
那么,能不能不经过PHP这层,直接让Webserver直接把文件发送给用户呢?
今天,我看到了一个有意思的文章:HowIPHP:X-SendFile.
我们可以使用Apache的modulemod_xsendfile,让Apache直接发送这个文件给用户:
<?php
$file="/tmp/中文名.tar.gz";
$filename=basename($file);
header("Content-type:application/octet-stream");
//处理中文文件名
$ua=$_SERVER["HTTP_USER_AGENT"];
$encoded_filename=rawurlencode($filename);
if(preg_match("/MSIE/",$ua)){
header("Content-Disposition:attachment;filename="".$encoded_filename.""");
}elseif(preg_match("/Firefox/",$ua)){
header("Content-Disposition:attachment;filename*=\"utf8""".$filename.""");
}else{
header("Content-Disposition:attachment;filename="".$filename.""");
}
//让Xsendfile发送文件
header("X-Sendfile:$file");
X-Sendfile头将被Apache处理,并且把响应的文件直接发送给Client.
Lighttpd和Nginx也有类似的模块,大家有兴趣的可以去找找看
相关文章
- php和asp网络验证码,Verifycode 1个简单的网页图片验证码的示例程序,基本上现有 字和字母都可以识别。 WEB(ASP,PHP,…) 238万源代码下载- www.pudn.com…
- PHP之与或非_php字符串运算符
- Linux更新:升级PHP版本(linux更新php版本)
- Linux 查看 PHP 版本的方法(linux查php版本)
- MySQL扩展:为PHP带来强大的数据库支持(php的mysql扩展)
- ajax下载文件的方法 php下载图片的方法详解编程语言
- 搭建 PHP 环境,在 Linux 系统里更轻松!(php环境linux)
- PHP的MySQL编程示例(php的mysql代码)
- 解决PHP读取MSSQL数据库乱码问题(php读mssql乱码)
- Linux平台如何高效搜索PHP文件(linux搜索php)
- 如何在PHP中使用MySQL数据库(mysql中php)
- 使用PHP连接Redis应用的指南(redis连接 php)
- PHP操作Redis快速读写数据(redis 读写 php)
- php下载远程文件类(支持断点续传)
- php做下载文件的实现代码及文件名中乱码解决方法
- php中强制下载文件的代码(解决了IE下中文文件名乱码问题)
- 让PHP更快的提供文件下载的代码
- php获取本地图片文件并生成xml文件输出具体思路
- 解析PHP实现下载文件的两种方法
- php对csv文件的读取,写入,输出下载操作详解
- php读取csv实现csv文件下载功能
- PHP读取文件内容后清空文件示例代码
- php实现文件下载实例分享
- PHP利用header跳转失效的解决方法
- 在Nginx中使用X-Sendfile头提升PHP文件下载的性能(针对大文件下载)