我需要使用PHP
和身份验证从我的Web服务器提供非常大的文件(1Gb+),这样只有一些客户有权下载文件。
我不想使用直接链接,并且由于内存和超时限制,使用PHP
脚本来提供文件不是一个选项。
我的Web服务器使用Plesk
进行管理,并在Apache
/CentOS
6上运行。
选择的解决方案是在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和vhostrongsl.conf,对于存储在中的虚拟主机
/var/www/vhosts/system/[yourvhostname]/conf
您可以通过ssh或使用Plesk UI界面(vhost->serversettings->其他apache指令)编辑它们。对于非Plesk用户,只需在httpd.conf 的正确vhost部分下添加以下指令
第一次我遇到一些问题是因为服务器发送了0字节的文件,经过一些测试,我发现正确的指令是:
<Directory "/">
EnableSendfile on
XSendFile on
# Absolute path, no trailing slash!
XSendFilePath "/var/www/vhosts/[yourvhostname]/storage"
</Directory>
注意,如果我使用与"/"不同的目录指令,我会得到空文件,并且在任何日志上都没有任何错误。没有通过在标头中传递相对路径来测试会发生什么。
因为我使用Laravel作为PHP框架,然后可以使用将文件发送给用户
return response(null)
->header('Content-Type' , 'application/octet-stream')
->header('Content-Disposition', 'attachment; '.$filename)
->header('X-Sendfile', $fullfilepath);
希望这能帮助人们避免数小时的测试。
Dario上面的评论真的很有帮助。我只是想添加我用于Laravel返回语句的内容,以确保文件的名称正确:
return response(null)
->header('Content-Type' , 'application/octet-stream')
->header('Content-Disposition', 'attachment; filename="' . $filename . "')
->header('X-Sendfile', $fullfilepath);