ホームページ > php教程 > php手册 > PHP でファイルのダウンロードを高速化できるようにする

PHP でファイルのダウンロードを高速化できるようにする

WBOY
リリース: 2016-06-21 08:51:48
オリジナル
944 人が閲覧しました

一般的に、ドキュメント ルートの下にあるファイルへの 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 . '"');

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

見た目はかなり良くなりましたが、まだ問題があり、それは 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 . '"');

} else {

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

}

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

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

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

Lighttpd と Nginx にも同様のモジュールがありますので、興味があればチェックしてみてください

X-Sendfile ヘッダーは Apache によって処理され、応答ファイルはクライアントに直接送信されます。



関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート