我以前的回答是不完整的,没有很好的记录,这里是更新,其中总结了该解决方案以及讨论中其他人员的解决方案。
从最佳解决方案到最坏解决方案的顺序排列,也从需要对Web服务器进行最多控制的解决方案到需要较少控制的解决方案进行排序。拥有一个既快速又可以在任何地方工作的解决方案似乎并不是一个简单的方法。
使用X-SendFile标头
正如其他人所记录的那样,这实际上是最好的方法。其基础是您使用php进行访问控制,然后您自己告诉文件服务器,而不是自己发送文件。
基本的php代码是:
header("X-Sendfile: $file_name");header("Content-type: application/octet-stream");header('Content-Disposition: attachment; filename="' . basename($file_name) . '"');$file_name文件系统上的完整路径在哪里。
该解决方案的主要问题在于,它必须由Web服务器允许,或者默认情况下未安装(apache),默认情况下未激活(lighttpd),或者需要特定的配置(nginx)。
apache
在apache下,如果您使用mod_php,则需要安装一个名为mod_xsendfile的模块,然后对其)进行配置(如果允许,可以在apacheconfig或.htaccess中)
XSendFile onXSendFilePath /home/www/example.com/htdocs/files/
使用此模块,文件路径可以是绝对路径,也可以是相对于指定路径的路径
XSendFilePath。
Lighttpd
在配置时,mod_fastcgi支持此功能
"allow-x-send-file" => "enable"
该功能的文档位于lighttpd Wiki上,它们记录了
X-LIGHTTPD-send-file标头,但
X-Sendfile名称也起作用
Nginx的
在Nginx上,您不能使用
X-Sendfile标题,而必须使用自己的标题为的标题
X-Accel-Redirect。默认情况下启用它,唯一的真正区别是它的参数应该是URI而不是文件系统。结果是您必须在配置中定义一个标记为内部的位置,以避免客户端找到真实的文件url并直接进入该URL,他们的Wiki对此做了很好的解释。
符号链接和位置标题
您可以使用符号链接并将其重定向到它们,只需在授权用户访问文件并将文件重定向至该文件时,使用随机名称创建指向文件的符号链接即可:
header("Location: " . $url_of_symlink);显然,当调用创建它们的脚本时或通过cron(如果可以访问,请在计算机上,否则通过某些Webcron服务),您将需要一种修剪它们的方法。
在apache下,您需要能够
FollowSymlinks在
.htaccess或apache配置中启用。
通过IP和位置标头进行访问控制
另一个技巧是从php生成apache访问文件,从而允许显式用户IP。在apache下,这意味着使用
mod_authz_host(
mod_access)
Allowfrom命令。
问题在于,锁定对文件的访问(因为多个用户可能希望同时执行此操作)并非易事,并且可能导致某些用户等待很长时间。而且您仍然需要修剪该文件。
显然,另一个问题是同一IP后面的多个人可能会访问该文件。
当其他一切都失败了
如果您真的没有办法让您的Web服务器来帮助您,则剩下的唯一解决方案是readfile,它可以在当前使用的所有php版本中使用,并且运行良好(但效率不高)。
组合解决方案
好的,如果您希望自己的php代码在任何地方都可以使用,那么真正快速发送文件的最佳方法是在某处有一个可配置的选项,其中说明了如何根据Web服务器激活它的说明以及安装过程中的自动检测脚本。
这与许多软件中完成的工作非常相似
- 清理网址(
mod_rewrite
针对Apache) - 加密函数(
mcrypt
php模块) - 多字节字符串支持(
mbstring
php模块)



