PHP経由でファイルを出力

PDFや画像をPHP経由でダウンロード

PHP

/** * * PHP経由でファイルを出力 * * @param string $file_name * @param string $load_name */ function loadFile($file_name, $load_name = '') { // 存在チェック if (! file_exists($file_name)) { exit; } // 読込許可をチェック if (! is_readable($file_name)) { exit; } // ファイル情報 $path_parts = pathinfo($file_name); // 拡張子を小文字置換 $file_ext = strtolower($path_parts['extension']); // 拡張子によるContent-TypeとContent-Dispositionの設定 if ($file_ext == 'pdf') { $content_type = 'application/pdf'; } elseif ($file_ext == 'gif') { $content_type = 'image/gif'; } elseif ($file_ext == 'jpg' || $file_ext == 'jpeg') { $content_type = 'image/jpeg'; } elseif ($file_ext == 'png') { $content_type = 'image/png'; } else { $content_type = 'application/octet-stream'; } if (preg_match('/^(gif|jpe?g|png)$/', $file_ext)) { // inline ブラウザに表示 $content_disposition = 'inline'; } else { // attachment ダウンロード $content_disposition = 'attachment'; } // ロードするファイル名が未定義の場合は元ファイル名と同じに if (empty($load_name)) { $load_name = $path_parts['filename']; } // ヘッダ header('Cache-Control: public'); header('Pragma: public'); header('Content-Type: ' . $content_type); header('Content-Disposition: ' . $content_disposition . '; filename=' . $load_name); // ファイル読込 // 20M以下 if (filesize($file_name) < 20971520) { readfile($file_name); } else { // ファイルサイズが大きくreadfileでうまくいかない場合 // (主に画像以外のファイル、20M程度が分岐目安) $fp = fopen($file_name, 'rb'); $contents = ''; while (! feof($fp)) { $contents .= fgets($fp, 8192); } fclose($fp); echo $contents; } exit; }

Cache-Control: public と Pragma: public の記述がないと、HTTPS(IEのみ?)ではno-cache扱いとなり、ファイルのダウンロードに失敗する。
そのためページのキャッシュ設定の記述が必要。
SSL 経由でファイルのダウンロードを Internet Explorer キャッシュ コントロール ヘッダーが動作しません。及び Content-Disposition: attachemnt と Cache-Control: no-cache によるダウンロードの問題を参照。

サンプル

最新の記事

プロフィール

流されるままにウェブ業界で仕事しています。
主にLAPP環境でPHPを書いています。
最近はjQueryをよく書いています。