使用linux上的mod_xsendfile下载PHP大文件

时间:2016-04-30 14:19:01

标签: php linux apache plesk x-sendfile

我需要使用PHP和身份验证从我的网络服务器提供非常大的文件(1Gb +),这样只有部分客户才有权下载文件。

我不想使用直接链接,并且由于内存和超时限制,使用PHP脚本来提供文件不是一个选项。

我的网络服务器由Plesk管理,并在Apache / CentOS 6上运行。

2 个答案:

答案 0 :(得分:4)

选择的解决方案是在Centos服务器上安装mod_xsendfile,配置它并在用户身份验证后使用PHP头发送文件。

在Centos上安装mod_xsendfile。你需要启用EPEL存储库来获取xsendfile,之后就是一个简单的:

yum update
yum install mod_xsendfile

之后,您可以使用以下方法检查模块是否正确安装:

apachectl -M | grep xsendfile

配置/ Plesk部分。 Plesk自动生成每个httpd.conf文件,因此手动修改文件是危险的,因为它们可以被Plesk UI完成的任何更改覆盖。默认情况下,http.conf文件包含vhost.conf和vhost_ssl.conf,用于存储在

中的虚拟主机
/var/www/vhosts/system/[yourvhostname]/conf

您可以通过ssh或使用Plesk UI界面(vhost - >服务器设置 - >其他apache指令)进行编辑。对于非Plesk用户,只需在httpd.conf

的正确vhost部分下添加以下指令

我第一次遇到一些问题导致服务器发送0字节文件,经过一些测试我发现正确的指令是:

<Directory "/">

    EnableSendfile on

    XSendFile on

    # Absolute path, no trailing slash!
    XSendFilePath "/var/www/vhosts/[yourvhostname]/storage"

</Directory>

注意,如果我使用与“/”不同的Directory指令,我会得到空文件,并且在任何日志上都没有错误。没有通过在标题中传递相对路径来测试会发生什么。

因为我使用Laravel作为PHP框架,然后可以将文件发送给用户:

   return response(null)
       ->header('Content-Type' , 'application/octet-stream')
       ->header('Content-Disposition', 'attachment; '.$filename)
       ->header('X-Sendfile', $fullfilepath);

希望这可以帮助有人避免数小时的测试。

答案 1 :(得分:2)

Dario上面的评论非常有帮助。我只是想添加我用于Laravel return语句的内容,以确保文件名称正确:

return response(null)
    ->header('Content-Type' , 'application/octet-stream')
    ->header('Content-Disposition', 'attachment; filename="' . $filename . "')
    ->header('X-Sendfile', $fullfilepath);