• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ファイルの保存について)

ファイルの保存について

このQ&Aのポイント
  • PHPとMySqlで簡易的なCMSを作成し、記事の保存方法について悩んでいます。
  • 記事にはタイトル、本文、最大6枚の画像が含まれており、ファイルの保存方法を検討しています。
  • 画像はバイナリデータとして保存するか、ファイルのパスをテキストで保存するか、どちらが良いでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
noname#244856
noname#244856
回答No.2

FileInfoクラス(関数)の出番です。 http://www.php.net/manual/ja/function.finfo-open.php <?php // FileInfoのインスタンスを生成(MIMEタイプを返すように設定) $finfo = finfo(FILEINFO_MIME_TYPE); // 許可するリスト(MIMEタイプ => 拡張子) $list = array(  'image/png' => 'png',  'image/gif' => 'gif',  'image/jpeg' => 'jpg',  'application/pdf' => 'pdf',  'application/msword' => 'doc', ); // ファイル名 $filename = 'example.png'; // MIMEタイプ取得(失敗したときはFALSE) $mime = $finfo->file($filename); // 許可しているものかどうかチェック if (isset($list[$mime])) {  $ext = $list[$mime]; } else {  throw new RuntimeException('許可されていないファイル形式です'); } ?> のように連想配列+issetで実装したほうがきれいかもしれません。

dcx147
質問者

お礼

お返事遅くなり申し訳ございません。 FileInfoが動くサーバー仕様だったのでこちらで対応してみようと思います! 参考になるアドバイスをありがとうございました^^

その他の回答 (2)

noname#244856
noname#244856
回答No.3

【訂正】 $finfo = finfo(FILEINFO_MIME_TYPE); ↓ $finfo = new finfo(FILEINFO_MIME_TYPE);

noname#244856
noname#244856
回答No.1

結論から言うと一長一短なので、CMSの特徴に合わせていずれかを選択してください。 【バイナリデータをデータベースに登録する】 (1) 表示するときに(まだファイルが存在しない場合は)バイナリデータを引き出してファイルとして公開テンポラリディレクトリに保存し、それを<img src="image_0001.jpg">などとして読み込む 公開テンポラリディレクトリ内のファイルは一定周期で削除するなどしてください。一時ファイル名を複雑にすればセキュリティ的には十分に安全だと思います。 (2) <img src="display_image.php?id=0001">としてPHPスクリプトを呼び出し、その中でヘッダーとともに引き出してきたバイナリデータを直接出力する (1)のようにキャッシュを効かせることが出来ないので少しサーバーに負荷がかかりますが、一時ファイルの後始末をする必要がありません。セキュリティ的には非常に強固です。 【ファイルとして保存する】 (3) 公開ディレクトリに保存する 最もシンプルな方法ですが、セキュリティ的には脆いです。一方、サーバーに対する負荷は非常に少ないです。 (4) 非公開ディレクトリに保存し、<img src="display_image.php?id=0001">としてPHPスクリプトを呼び出し、その中でヘッダーとともにバイナリデータを直接出力する PHPファイルを通して間接的に非公開ディレクトリのファイルデータを表示する方法ですが、これを採用するのであれば(2)を使うべきだと思います。セキュリティ的には非常に強固です。 また、拡張子を $ext = pathinfo($img_path, PATHINFO_EXTENSION); で調べるのはやめたほうがいいと思います。 拡張子が偽装されていたり省略されている場合に対応できません。 それよりもバイナリデータを見て (全角スペースでインデントしているので注意) $info = getimagesize($img_path); switch (true) {  case $info === false:   throw new RuntimeException('画像ファイルではありません');  case $info['mime'] === 'image/jpeg':   $ext = 'jpg';   break;  case $info['mime'] === 'image/png':   $ext = 'png';   break;  case $info['mime'] === 'image/gif':   $ext = 'gif';   break;  default:   throw new RuntimeException('非対応の画像形式です'); } などとしてMIMEタイプで判別すべきです。 (例外はキャッチして適切に処理してください)

dcx147
質問者

お礼

参考になるご意見ありがとうございます。 引き続き自分でも調べていましたが、確かに一長一短なようですね。 画像ファイルだけじゃないことがやっかいです^^; セキュリティ的に・・・ですが、公開ディレクトリに保存する方法で シンプルに実装しようかと思ってました。 拡張子とmimeタイプのチェックは、しっかり行うつもりですが 画像は、getimagesizeで情報を取得して拡張子とmimeタイプを取得するにしても pdfやwordなどのファイルは何で取得するのがいいでしょうか? $ext = pathinfo($img_path, PATHINFO_EXTENSION); で取得してから、静的にmimeタイプを設定しようかと思っていました。 switch ( $str ) { case 'jpg': case 'jpeg': $mime = 'image/jpeg'; break; case 'gif': $mime = 'image/gif'; break; case 'pdf': $mime = 'application/pdf'; break; case 'doc': $mime = 'application/msword'; break; }

関連するQ&A

専門家に質問してみよう