关于PHP做文件下载效率优化和体验提升
2015年9月28日
没有评论
Web开发中我们经常会遇到需要PHP处理要下载的文件,比如需要用户登陆才能下载文件,被下载的文件不允许直接访问,下载后的文件需要重命名等,通常我们可以使用下面的代码实现:
<?php authenticate(); //权限判断 // 读取文件内容 $content=file_get_contents($file); // 发送合适的 HTTP 头 header("Content-type: application/octet-stream"); header('Content-Disposition: attachment; filename="' . basename($file) . '"'); header("Content-Length: ". filesize($file)); echo $content; // 或者 readfile($file); ?>
但是这样做性能极低,你可以想像用户每次下载的时候程序都会一次一次地经过一个固定的buffer读取文件内容到内存,再发送到前端服务器,最后才能发送到客户端,还有各种网络超时和大量内存消耗,这将会是一个相当糟糕的设计。下面将介绍一个更直接高效的方式来实现。
X-Sendfile 是一种将文件下载请求由后端转交给前端服务器,由前端服务器直接处理文件下载请求的一种机制。它可以有效缓解后端服务器压力,将文件下载请求直接将由擅长处理静态文件请求的前端服务器如:Nginx、Lighthttpd等,极大地提高了文件下载请求效率。
X-Sendfile是通过一个非标准化的特定HTTP header实现的,后端服务器发送一个特定的HTTP header到前端服务器的时候,前端服务器从X-Sendfile得到请求的文件地址后,前端服务器将利用自身的功能机制将文件直接发送给用户。
X-Sendfile实际上是一种服务器内部的跳转机制,这种处理请求并不会将实际需要请求的文件地址暴露给用户,X-Sendfile做为一种非标准化的机制,不同的服务器的实现有所区别
SENDFILE 头 | 使用的 WEB 器 |
---|---|
X-Sendfile | Apache, Lighttpd v1.5, Cherokee |
X-LIGHTTPD-send-file | Lighttpd v1.4 |
X-Accel-Redirect | Nginx, Cherokee |