多くの場合、ユーザーは Web サイトからファイルをダウンロードする必要があります。ファイルが固定リンクを通じて公開されている場合は、ファイルを webroot の下のディレクトリに保存するだけで済みます。ただし、ほとんどの場合、PDF 請求書のダウンロードやネットワーク ディスク内のファイルのダウンロードなど、アクセス許可を制御する必要があります。現時点では通常、スクリプト コードを使用して実装しますが、間違いなくサーバーの負荷が増加します。
たとえば、次のコード:
//ユーザー ID 認証、検証が失敗した場合はジャンプします
認証();
// ダウンロードするファイルを取得します。ファイルが存在しない場合はジャンプします
$file = destroy_file();
// ファイルの内容を読み取ります
$content=file_get_contents($file);
//適切な HTTP ヘッダーを送信します
header("Content-type: application/octet-stream");
header('Content-Disposition:attachment; filename="' .basename($file) .'"');
header("Content-Length: ".filesize($file));
echo $content; // または readfile($file);
?>1. これを行うとどのような問題がありますか?
これを行うには、プログラムがループ内の固定バッファーを介してディスクからファイルの内容をメモリに読み取り、それをフロントエンド Web サーバーに送信し、最終的にユーザーに到達する必要があることを意味します。ダウンロードするファイルが大きい場合、この方法は大量のメモリを消費し、PHP プロセスがタイムアウトまたはクラッシュすることもあります。中断と再接続は言うまでもなく、キャッシュも頭痛の種です。
理想的な解決策は、PHP プログラムに権限チェックなどの論理的な判断を実行させ、すべてが合格した後、フロントエンド Web サーバーがファイルをユーザーに直接送信できるようにすることです。Nginx のようなフロントエンドは静的ファイルの処理に優れています。ファイル。こうすることで、PHP スクリプトが I/O によってブロックされなくなります。
2. X-Sendfileとは何ですか?
X-Sendfile は、ファイルのダウンロード要求をバックエンド アプリケーションからフロントエンド Web サーバーに転送して処理するメカニズムで、ファイルの読み取りと送信処理の両方に対するバックエンド プログラムの負担を軽減し、サーバーを大幅に改善します。特に大きなファイルを処理する場合の効率が向上します。
X-Sendfile は特定の HTTP ヘッダーを通じて実装されます。X-Sendfile ヘッダーにファイルのアドレスを指定して、フロントエンド Web サーバーに通知します。 Web サーバーは、バックエンドによって送信されたこのヘッダーを検出すると、バックエンドからの他の出力を無視し、独自のコンポーネント (ヘッダーのキャッシュやブレークポイントの再接続などの最適化を含む) を使用してファイルをユーザーに送信します。
ただし、X-Sendfile を使用する前に、これは標準機能ではなく、ほとんどの Web サーバーではデフォルトで無効になっていることを理解する必要があります。 Web サーバーが異なれば、X-Sendfile ヘッダー形式の規定など、実装も異なります。設定が正しくないと、ユーザーは 0 バイトのファイルをダウンロードする可能性があります。
X-Sendfile を使用すると、.htaccess 保護でアクセスが禁止されているファイルでも、Web 以外のディレクトリ (/root/ など) にあるファイルをダウンロードできます。
異なる Web サーバーは、使用される異なる HTTP ヘッダー sendfile ヘッダー Web サーバーを実装します
X-Sendfile Apache、Lighttpd v1.5、Cherokee
X-LIGHTTPD-send-file Lighttpd v1.4
X-Accel-Redirect Nginx、チェロキー
X-SendFile を使用する欠点は、ファイル転送メカニズムの制御を失うことです。たとえば、ファイルのダウンロード完了後に、ユーザーにファイルのダウンロードを 1 回だけ許可するなど、特定の操作を実行したい場合、バックグラウンドの PHP スクリプトはダウンロードが成功したかどうかを認識しないため、この X-Sendfile では実行できません。
3.使い方は?
Apache については、mod_xsendfile モジュールを参照してください。次にNginxの使い方を紹介します。
Nginx はデフォルトでこの機能をサポートしており、追加のモジュールをロードする必要はありません。実装が少し異なるだけで、送信する必要がある HTTP ヘッダーは X-Accel-Redirect です。さらに、設定ファイルで以下の設定を行う必要があります
場所 /protected/ {
内部;
root /some/path;
}internal は、このパスが Nginx 内でのみアクセスでき、不正なダウンロードを防ぐためにブラウザを使用して直接アクセスできないことを意味します。
したがって、PHP は X-Accel-Redirect を Nginx に送信します。
$filePath = '/protected/iso.img';
header('Content-type: application/octet-stream');
header('Content-Disposition:attachment; filename="' .basename($file) .'"');
//Xsendfile にファイルを送信させます
header('X-Accel-Redirect: '.$filePath);
?>このようにして、ユーザーはパス /some/path/protected/iso.img の下にファイルをダウンロードします。
/some/path/iso.img ファイルを送信したい場合、Nginx の設定は次のようにする必要があります
場所 /protected/ {
内部;
alias /some/path/; # 最後のスラッシュに注意してください