首页 > 程序开发 > PHP > nginx使用XSendfile模块让php更快下载文件实战
2015
01-12

nginx使用XSendfile模块让php更快下载文件实战

一般来说, 我们可以通过直接让URL指向一个位于Document Root下面的文件, 来引导用户下载文件.

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

我的webroot目录在/var/vhost/demo,demo目录中存在一个uploadfiles文件夹,这个文件夹是存放用户上传的文件。

比如一个用户上传一个hello.docx文件,那么它对应的物理路径应该是/var/vhost/uuling/xsendfile/hello.doc,如果我们以直接路径“http://www.uuling.com/xsendfile/hello.doc”来访问的话,那么我想对这个文件进行下载统计或者隐藏实体路径的话就只能使用php readfile()方法来把文件装载到内存中,在转发给客户端,如果文件超大的话,你的服务器估计很悬。
所以我们要改进php下载方式,就是引言所阐述的利用nginx的XSendfile方式来传送文件给客户端,nginx默认已经包含了senfile模块了,你如果安装完nginx你会在nginx.conf文件会看到“sendfile on;”,OK说明你可以直接使用了不像apache那么复杂还要重新加载组件编译等等。好了我贴下我的配置文件和代码。

nginx虚拟主机配置文件

server {
        listen 80;
        server_name demo.markdream.com;
 
        root /var/vhost/demo;
        index  index.php;
 
        # 这个是定义读取你的文件的目录的url开头  直接访问是不可以的 只能通过
        location /protected {
                internal;
                alias   /var/vhost/uuling/xsendfile/;
        }
 
        location ~ \.php$ {
           fastcgi_pass   127.0.0.1:9000;
           fastcgi_index  index.php;
           fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
           include        fastcgi_params;
        }
}

一个简单的php下载文件脚本,downloads.php

<?php
 
// 获取文件名
$filename = $_GET["filename"];
 
// 你可以在这里写下你的查询数据库等你所想的功能 ……
 
header ( "Content-type: application/octet-stream" );
// 处理中文文件名
$ua = $_SERVER ["HTTP_USER_AGENT"];
if (preg_match ( "/MSIE/", $ua )) {
 $encoded_filename = rawurlencode ( $filename );
 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 . '"' );
}
 
// 就这么简单一句话搞定 注意“protected”是和nginx配置文件的 protected要一致
header("X-Accel-Redirect: /protected/" . $filename);
 
?>
最后编辑日期:
作者:uuling
这个作者貌似有点懒,什么都没有留下。

留下一个回复

你的email不会被公开。