PHPを使用してファイルを効率的にレンダリングします

ファイルをWebサーバーに直接送信するのではなく、PHPを使用して(たとえば、ダウンロード統計を収集する)必要がある場合は、catを使用してください。

1. readfile()使用します


この方法は、ボックスで機能するため優れています。 ファイル送信関数を作成するだけです( 公式ドキュメントから少し変更した例):

 function file_force_download($file) { if (file_exists($file)) { //    PHP,        //          ! if (ob_get_level()) { ob_end_clean(); } //       header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . basename($file)); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . filesize($file)); //       readfile($file); exit; } } 

この方法では、PHPがファイルを読み取り、すぐに部分的にユーザーに提供するため、大きなファイルを送信することもできます。 ドキュメントには、 readfile()がメモリの問題を引き起こしてはならないと明記されています。

機能:

2.ファイルを手動で読み取り、送信する


このメソッドは、プライベートファイルシステムからファイルを送信するときに同じDrupalを使用します(ファイルはリンクを介して直接アクセスできません)。

 function file_force_download($file) { if (file_exists($file)) { //    PHP,        //          ! if (ob_get_level()) { ob_end_clean(); } //       header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . basename($file)); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . filesize($file)); //       if ($fd = fopen($file, 'rb')) { while (!feof($fd)) { print fread($fd, 1024); } fclose($fd); } exit; } } 

機能:

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; } } 

公式ドキュメントページの詳細

機能:


更新: ilyaplot habrayuzerは、 application/octet-streamを送信するのではなく、実際のMIMEタイプファイルを送信する方がよいという実用的なアドバイスを提供します。 たとえば、これにより、ブラウザは必要なプログラムをファイル保存ダイアログに置き換えることができます。

Source: https://habr.com/ru/post/J151795/


All Articles