PHPではX-SCendFileヘッダを使ってファイルのダウンロードをより速くします。

1962 ワード

一般的には、URLをDcument 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のreadfileはできるだけ効率的にPHP自体のメモリを使わないようにしようとしていますが、実際にはMMAP(サポートすれば)を採用したり、固定されているブザーを使ってファイルを循環して直接出力したりします。
出力する場合は、Apache+PHP modであれば、Apacheの出力バッファに送る必要があります。最後にユーザーに送ります。Ngix+fpmに対しては、彼らが別々に配置したら、追加のネットワークIOを持ってきます。
PHPを通さずにWebserverに直接ユーザーにファイルを送ってもいいですか?
今日、面白い文章を見ました。How I PHP:X-SeendFile。
私たちはApacheのmodule mod_を使うことができます。xsendfileは、Appacheにこのファイルをユーザーに直接送信させます。

<?php
    $file = "/tmp/ .tar.gz";

    $filename = basename($file);

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

    //
    $ua = $_SERVER["HTTP_USER_AGENT"];
    $encoded_filename = rawurlencode($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-Length: ". filesize($file));
    readfile($file);
X-indfileヘッダはAppacheによって処理され、応答のファイルを直接Clientに送ります。
LighttpdとNginnxにも似たようなモジュールがあります。興味があれば探してみてください。