在 Linux 上使用 mod_xsendfile 使用 PHP 下载大文件

Dar*_*rno 2 php linux apache x-sendfile plesk

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

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

我的网络服务器由/ 6管理Plesk并运行。ApacheCentOS

Dar*_*rno 5

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

在 Centos 上安装 mod_xsendfile。您需要启用 EPEL 存储库以获取 xsendfile,然后是一个简单的:

yum update
yum install mod_xsendfile
Run Code Online (Sandbox Code Playgroud)

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

apachectl -M | grep xsendfile
Run Code Online (Sandbox Code Playgroud)

配置/Plesk 部分。Plesk 会自动生成每个 httpd.conf 文件,因此手动修改文件是危险的,因为它们可能会被通过 Plesk UI 所做的任何更改覆盖。默认情况下,http.conf 文件包括 vhost.conf 和 vhost_ssl.conf,对于虚拟主机,它们存储在

/var/www/vhosts/system/[yourvhostname]/conf
Run Code Online (Sandbox Code Playgroud)

您可以通过 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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

希望这有助于某人避免数小时的测试。