一般的に、ドキュメント ルートの下にあるファイルへの URL を直接指定することで、ユーザーに ファイルをダウンロードする ように誘導できます。
ただし、これを行うと、一部の統計や権限チェックなどを行うことができなくなります。したがって、多くの場合、私たちは PHP を使用して、ユーザー にファイルのダウンロード を転送して提供します。
$file = "/tmp/dummy.tar.gz";
header("Content-type: application/octet-stream");
header('Content-Disposition:attachment; filename="' .basename($file) .'"');
)
$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-Length: “.filesize($file));
readfile($file);
出力する際、Apache + PHP modの場合はApacheの出力バッファにも送る必要があります。最終的にはユーザーに送信されます。 Nginx + fpm の場合、別々にデプロイすると、追加のネットワーク IO も発生します。
では、WebサーバーはPHP層を経由せずにユーザーに直接ファイルを送信できるでしょうか?
今日、興味深い記事を見つけました:How I PHP: X-SendFile。
Apache のモジュール mod_xsendfile を使用すると、Apache がこのファイルをユーザーに直接送信できるようになります:
$file = "/tmp/中文名.tar.gz";
} else if (preg_match("/Firefox/", $ua)) {
header("Content-Disposition:attachment; filename*="utf8''" . $filename . '"');
} その他 {
header('Content-Disposition:attachment; filename="' . $filename . '"');
//Xsendfile にファイルを送信させます
header("X-Sendfile: $file");
Lighttpd と Nginx にも同様のモジュールがありますので、興味のある方はチェックしてみてください。 X-Sendfile ヘッダーは Apache によって処理され、応答ファイルはクライアントに直接送信されます。