ファイルをWebサーバーに直接送信するのではなく、PHPを使用して(たとえば、ダウンロード統計を収集する)必要がある場合は、catを使用してください。
1. readfile()
使用します
この方法は、ボックスで機能するため優れています。 ファイル送信関数を作成するだけです(
公式ドキュメントから少し変更した例):
function file_force_download($file) { if (file_exists($file)) {
この方法では、PHPがファイルを読み取り、すぐに部分的にユーザーに提供するため、大きなファイルを送信することもできます。 ドキュメントには、
readfile()
がメモリの問題を引き起こして
はならないと明記されています。
機能:
- スクリプトは、ファイル全体が読み取られてユーザーに渡されるまで待機します。
- ファイルはreadfile()関数の内部バッファーに読み込まれ、そのサイズは8kBです( 2fast4rabbitに感謝)
2.ファイルを手動で読み取り、送信する
このメソッドは、プライベートファイルシステムからファイルを送信するときに同じDrupalを使用します(ファイルはリンクを介して直接アクセスできません)。
function file_force_download($file) { if (file_exists($file)) {
機能:
- スクリプトは、ファイル全体が読み取られてユーザーに渡されるまで待機します。
- サーバーのメモリを節約します
3. Webサーバーモジュールを使用します
3a。 アパッチ
XSendFileモジュールでは、特別なヘッダーを使用して、ファイル送信をApache自体に転送できます。 UnixおよびWindowsにはバージョン2.0の下にバージョンがあります。*、2.2。*および2.4。*
ホスト設定で、ディレクティブを使用してヘッダーキャプチャを有効にする必要があります。
XSendFile On
ファイルを処理できるディレクトリのホワイトリストを指定することもできます。
重要:Windowsベースのサーバーを使用している場合、パスにはドライブ文字を大文字で含める必要があります。開発者のサイトで可能なオプションの説明:
https :
//tn123.org/mod_xsendfile/ファイルを送信する例:
function file_force_download($file) { if (file_exists($file)) { header('X-SendFile: ' . realpath($file)); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . basename($file)); exit; } }
3b。 Nginx
Nginxは、特別なヘッダーを介して箱から出してファイルを送信できます。
正常に動作させるには、構成ファイルから直接フォルダーへのアクセスを拒否する必要があります。
location /protected/ { internal; root /some/path; }
ファイルを送信する例(ファイルはディレクトリ/ some / path / protectedにある必要があります):
function file_force_download($file) { if (file_exists($file)) { header('X-Accel-Redirect: ' . $file); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . basename($file)); exit; } }
公式ドキュメントページの詳細
機能:
- スクリプトは、すべての指示が完了するとすぐに終了します。
- 物理的には、ファイルはPHPではなくWebサーバー自体のモジュールによって送信されます
- 最小限のメモリとサーバーリソースの消費
- 最大のパフォーマンス
更新: ilyaplot
habrayuzerは、
application/octet-stream
を送信するのではなく、実際のMIMEタイプファイルを送信する方がよいという
実用的なアドバイスを提供します。 たとえば、これにより、ブラウザは必要なプログラムをファイル保存ダイアログに置き換えることができます。