ホームページ  >  記事  >  バックエンド開発  >  PHP でユーザーにファイルをより速くダウンロードできるようにする_PHP チュートリアル

PHP でユーザーにファイルをより速くダウンロードできるようにする_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-21 14:51:471039ブラウズ

一般的に、ドキュメント ルートの下にあるファイルへの URL を直接指定することで、ユーザーに ファイルをダウンロードする ように誘導できます。


ただし、これを行うと、一部の統計や権限チェックなどを行うことができなくなります。したがって、多くの場合、私たちは 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 = ベース名($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 . '"');

} その他 {


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 も発生します。


見た目はかなり良くなりましたが、まだ問題があり、それは PHP の readfile です。PHP の readfile は可能な限り効率的であり、PHP 自体のメモリを占有しないように努めていますが、実際には MMAP (サポートされている場合) を使用する必要があります。 、または、固定バッファを使用してファイルを周期的に読み取り、直接出力します。


では、WebサーバーはPHP層を経由せずにユーザーに直接ファイルを送信できるでしょうか?

今日、興味深い記事を見つけました:How I PHP: X-SendFile。

Apache のモジュール mod_xsendfile を使用すると、Apache がこのファイルをユーザーに直接送信できるようになります:

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

$filename = ベース名($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 . '"');

} その他 {

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

}


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


//Xsendfile にファイルを送信させます


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


Lighttpd と Nginx にも同様のモジュールがありますので、興味のある方はチェックしてみてください。 X-Sendfile ヘッダーは Apache によって処理され、応答ファイルはクライアントに直接送信されます。


www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/371720.html技術記事一般に、ドキュメント ルートの下にあるファイルへの URL を直接指定することで、ユーザーにファイルをダウンロードするように誘導できます。 ただし、これを行うと、一部の統計と権限ができなくなります...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。