让PHP更快的提供文件下载

  一般来说, 我们可以通过直接让URL指向一个位于Document Root下面的文件, 来引导用户下载文件.

  但是, 这样做, 就没办法做一些统计, 权限检查, 等等的工作. 于是, 很多时候, 我们采用让PHP来做转发, 为用户提供文件下载.

 

  <?php

  $file = "/tmp/dummy.tar.gz";

  header("Content-type: application/octet-stream");

  header('Content-Disposition: attachment; filename="' . basename($file) . '"');

  header("Content-Length: ". filesize($file));

  readfile($file);

 

  但是这个有一个问题, 就是如果文件是中文名的话, 有的用户可能下载后的文件名是乱码.

  于是, 我们做一下修改(参考: :

 

  <?php

  $file = "/tmp/中文名.tar.gz";

  $filename = basename($file);

  header("Content-type: application/octet-stream");

  //处理中文文件名

  $ua = $_SERVER["HTTP_USER_AGENT"];

  $encoded_filename = urlencode($filename);

  $encoded_filename = str_replace("+", "%20", $encoded_filename);

  if (preg_match("/MSIE/", $ua)) {

  header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');

  } else if (preg_match("/Firefox/", $ua)) {

  header("Content-Disposition: attachment; filename*=\"utf8''" . $filename . '"');

  } else {

  header('Content-Disposition: attachment; filename="' . $filename . '"');

  }

  header('Content-Disposition: attachment; filename="' . $filename . '"');

  header("Content-Length: ". filesize($file));

  readfile($file);

 

  恩, 现在看起来好多了, 不过还有一个问题, 那就是readfile, 虽然PHP的readfile尝试实现的尽量高效, 不占用PHP本身的内存, 但是实际上它还是需要采用MMAP(如果支持), 或者是一个固定的buffer去循环读取文件, 直接输出.

  输出的时候, 如果是Apache + PHP mod, 那么还需要发送到Apache的输出缓冲区. 最后才发送给用户. 而对于Nginx + fpm如果他们分开部署的话, 那还会带来额外的网络IO.

  那么, 能不能不经过PHP这层, 直接让Webserver直接把文件发送给用户呢?

  今天, 我看到了一个有意思的文章: How I PHP: X-SendFile.

  我们可以使用Apache的module mod_xsendfile, 让Apache直接发送这个文件给用户:

 

  <?php

  $file = "/tmp/中文名.tar.gz";

  $filename = basename($file);

  header("Content-type: application/octet-stream");

  //处理中文文件名

  $ua = $_SERVER["HTTP_USER_AGENT"];

  $encoded_filename = urlencode($filename);

  $encoded_filename = str_replace("+", "%20", $encoded_filename);

  if (preg_match("/MSIE/", $ua)) {

  header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');

  } else if (preg_match("/Firefox/", $ua)) {

  header("Content-Disposition: attachment; filename*=\"utf8''" . $filename . '"');

  } else {

  header('Content-Disposition: attachment; filename="' . $filename . '"');

  }

  header('Content-Disposition: attachment; filename="' . basename($file) . '"');

  //让Xsendfile发送文件

  header("X-Sendfile: $file");

 

  X-Sendfile头将被Apache处理, 并且把响应的文件直接发送给Client.

  Lighttpd和Nginx也有类似的模块, 大家有兴趣的可以去找找看

时间: 2024-08-31 09:32:10

让PHP更快的提供文件下载的相关文章

让 PHP 更快的提供文件下载

一般来说, 我们可以通过直接让URL指向一个位于Document Root下面的文件, 来引导用户下载文件. 但是, 这样做, 就没办法做一些统计, 权限检查, 等等的工作. 于是, 很多时候, 我们采用让PHP来做转发, 为用户提供文件下载. $file = "/tmp/dummy.tar.gz"; header("Content-type: application/octet-stream"); header('Content-Disposition: atta

让PHP更快的提供文件下载的代码_php技巧

但是, 这样做, 就没办法做一些统计, 权限检查, 等等的工作. 于是, 很多时候, 我们采用让PHP来做转发, 为用户提供文件下载. 复制代码 代码如下: <?php $file = "/tmp/dummy.tar.gz"; header("Content-type: application/octet-stream"); header('Content-Disposition: attachment; filename="' . basename

让PHP更快的为用户提供文件下载

一般来说,我们可以通过直接让URL指向一个位于Document Root下面的文件,来引导用户下载文件. 但是,这样做,就没办法做一些统计,权限检查,等等的工作.于是,很多时候,我们采用让PHP来做转发,为用户提供文件下载. $file = "/tmp/dummy.tar.gz": header("Content-type: application/octet-stream"): header('Content-Disposition: attachment: fi

与阿里云整个生态体系共同成长,更快更好的为房地产行业客户提供高价值的服务。

免费开通大数据服务:https://www.aliyun.com/product/odps "最早是新业务要做,但是买服务器来不及,管理员没到位,而且新业务的成本很高,是否能成功也是未知,因此明源决定采用阿里云,等资金和人到位再搬到自己内部.然而就是这种误打误撞,却让明源抓住了一个很好的机会走在了正确的轨道上."--副总裁童继龙 "阿里云数加的覆盖面很广,从存储.计算到上层应用,提供了一整套的解决方案,确实起到了马总说的普惠大数据.此外,数加也在不断的迭代,不停的有新产品出现

INTEL SECURITY 发布新的企业战略,旨在提供更好的保护、更快的检测和精简的修正流程

Intel Security 于10月30日宣布其旨在使全球企业更加积极而有效地抵御数据威胁和有针对性攻击的新的企业战略.通过一个将威胁防御生命周期主要阶段统一在一起的更集成且更开放的安全系统,这一新的战略将终端和云作为实现高级可视性和实用运营控制的最有效方面加以关注.这些控制点由世界级检测和分析技术支持.这一战略还重点强调了通过涵盖 Intel 及第三方产品的集中管理和互联架构简化用户体验.借助这一开放的集成系统,Intel Security 的目标是使企业能够利用较少的资源更快地应对更多威胁

虚拟现实的未来:需提供更快的网速和更多的数据中心

罗伯特·斯考伯是一位投资UploadVR项目的企业家,他工作在开发虚拟现实技术的前沿.UploadVR项目是针对全球虚拟现实的专业人员开发的多媒体平台,斯考伯作为行业一位先驱,测试了MagicLeap和Oculus的最新技术. "在未来的五年中,我们将看到一个惊人的变化,"斯考伯说,"这是令人兴奋的.人们将被其快速发展的速度表示震惊."如果它被广泛采用,虚拟现实可能会对网络和数据中心产生一个令人兴奋的影响. "这将需要大量的软件和大量的基础设施,"

让跨国公司数据传输更快,Viptela用SD-WAN技术提供广域网服务

Viptela是一家提供虚拟广域网技术的公司,致力于使用SD-WAN技术为跨国企业提供更安全可控.性价比更高的网络服务. 具体来说,企业可以通过购买Viptela的许可证进行虚拟网络线路的快速部署,也可以直接购买其硬件设备,只要设备接通了电源及网络,就能自动接入Viptela云端,进行识别认证后便可接入Viptela的线路.Viptela称,除了记录网络地址,其云服务不会读取和存储用户的任何信息. 目前Viptela的三种设备vEdge100.vEdge1000和vEdge2000可分别提供10

在PHP中使用X-SendFile头让文件下载更快_php实例

一般来说, 我们可以通过直接让URL指向一个位于Document Root下面的文件, 来引导用户下载文件. 但是, 这样做, 就没办法做一些统计, 权限检查, 等等的工作. 于是, 很多时候, 我们采用让PHP来做转发, 为用户提供文件下载. 复制代码 代码如下: <?php    $file = "/tmp/dummy.tar.gz";    header("Content-type: application/octet-stream");    head

异步加载:ControlJS让脚本加载更快的一个模块

文章简介:关于ControlJs的使用和基础讲解. 关于ControlJs一共有三篇文章,这是第一部分.ControlJS是让脚本加载更快的一个模块(a javascript module for making scripts load faster). 三篇文章的结构分别为: 1. async loading2. delayed execution3.overriding document.write关于第一部分的异步加载,这个的关键在于尽快将页面作为html绘制出来,然后再用javascri