知识大全 让PHP更快的为用户提供文件下载

Posted 文件

篇首语:峥嵘过去已经彪炳史册,璀璨当下正在不断延伸,光明未来需要踏实开拓。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 让PHP更快的为用户提供文件下载相关的知识,希望对你有一定的参考价值。

让PHP更快的为用户提供文件下载  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

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

   但是 这样做 就没办法做一些统计 权限检查 等等的工作 于是 很多时候 我们采用让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)

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

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

   $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(“+” “% ” $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*=”utf “ $filename ” )

   else

   header( Content Disposition attachment filename=“ $filename ” )

  

   header( Content Disposition attachment filename=“ $filename ” )

   header(“Content Length “ filesize($file))

   readfile($file)

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

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

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

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

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

   $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(“+” “% ” $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*=”utf “ $filename ” )

   else

   header( Content Disposition attachment filename=“ $filename ” )

  

   header( Content Disposition attachment filename=“ basename($file) ” )

   //让Xsendfile发送文件

   header(“X Sendfile $file”)

cha138/Article/program/PHP/201311/21065

相关参考