我当前正在使用以下 PHP 函数来允许用户选择文件然后下载它。这通过 FTP 发生。但是,如果用户选择大文件,那么在下载时,它会锁定服务器以应对任何其他请求。有什么方法可以在让 PHP 继续响应请求的同时托管该文件吗?
我需要 PHP 来验证用户是否有权使用其凭据下载该文件,因此我不能仅将其作为 Assets 托管。该文件位于 FTP 服务器上。
function download($file) {
$fileStream = "";
if($this->get($file)) {
//Send header to browser to receive a file
header("Content-disposition: attachment; filename=\"$file\"");
header("Content-type: application/octet-stream");
header("Pragma: ");
header("Cache-Control: no-cache");
header("Expires: 0");
$data = readfile($this->downloadDir . $file);
$i=0;
while ($data[$i] != "")
{
$fileStream .= $data[$i];
$i++;
}
unlink($this->downloadDir . $file);
echo $fileStream;
exit;
} else {
return false;
}
}
最佳答案
PHP 并不是此类工作的最佳解决方案,但它可以将工作委托(delegate)给您正在使用的 Web 服务器。由于该文件与您的应用程序位于同一位置,因此这是可行的。
通常运行 PHP 应用程序的所有主要 Web 服务器( Apache 、 lighttpd 和 nginx )都支持 XSendfile
。
要使用它,您必须首先在 Web 服务器中启用该功能(检查上面每个 Web 服务器的链接),然后在脚本中添加新 header :
Apache :
header("X-Sendfile: $location_of_file_to_download");
Lighttpd:
header("X-LIGHTTPD-send-file: $location_of_file_to_download");
nginx:
header("X-Accel-Redirect: $location_of_file_to_download");
Web 服务器将从您的应用程序捕获此 header ,并用该文件替换 PHP 响应的正文。当它将此文件发送给用户时,PHP 就会解锁并准备好为新用户提供服务。
(其他 header 将保留,因此您可以保留内容类型和内容处置 header )
关于PHP 如何正确托管大文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14430102/