ファイルの保存について

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

ファイルの保存について

PHPとMySqlで簡易的なCMSを作成しています。 1つの記事にタイトルと本文と画像(最大)6枚を登録します。 表示のイメージはこんな感じです。 「タイトル(テキストのみ)」 「画像1」「画像2」「画像3」 「画像4」「画像5」「画像6」 「本文(テキストのみ)」 「ワード(クリックするとダウンロード)」 「PDF(クリックするとブラウザで開く)」 ファイルのアップロードは、本文とは別の項目です。 画像の他にPDFやワードなどのファイルもアップロード可能です。 アップしたファイルのパス(files/img.jpgのようなテキスト)だけをtext型のカラムに登録しようと思っていたのですが、セキュリティ的に画像はバイナリデータとして保存した方がいいとか。。。 $img_path = '画像のパス'; $img = file_get_contents($img_path); $ext = pathinfo($img_path, PATHINFO_EXTENSION); こんな感じで、バイナリデータと拡張子を分けて登録するようです。 ファイルは、バイナリデータとして登録しアップロードされたフォルダから消す方法と パスをテキストで登録しファイルを残しておく方法とはどちらがいいのでしょうか?

  • dcx147
  • お礼率33% (214/636)
  • PHP
  • 回答数3
  • ありがとう数14

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

  • ベストアンサー
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

  • ファイルをダウンロードして展開するようにしたい

    urizakaです。 さて、JSP+SQL-Server2000でExcel等のファイルをバイナリデータとしてDB のimageフィールドに登録して、それをダウンロードするというプログラムを 組んでおり、なんとかファイル名とそのバイナリ-データをアップロードすることはできるようになったのですが、その後、バイナリ-データをDBからダウンロードして、その後にどのようにすれば良いのかが分かりません。  バイナリ-データをDBから検索して持ってきて、ブラウザー上でそのファイルが展開されるようにしていのですが…(よくPDFのサイトを開くと、自動的にPDFが展開されるように)  バイナリ-データにファイル名とそのファイルのタイプを与えてやれば良いような気もするのですが、それをどうやって与えてやればいいのかも皆目見当がつきません。すみませんが、ご存知の方がいらっしゃったら教えてください。  宜しくお願いします。

    • ベストアンサー
    • Java
  • バイナリファイルなのですが・・・。

    研究用のデータを受け取ったのですが、テキストではなくバイナリファイルでもらいました。データを取得した人によると、↓にある装置を使って時系列データをintel86系バイナリフォーマットで記録したと言っていました。 http://www.sonysms.co.jp/j/products/datarecorder/pdf/SONY_PCscan3_jp.pdf どうにかしてこのバイナリファイルをテキストに変換して、データを取得したいのですが、どうしたらよいのでしょうか? ネットにあるバイナリ→テキスト変換ツールを使いましたが、16進数の数字が羅列されるだけで、エクセルなどで読めるデータ形式にはなりませんでした。

  • テキストファイルのアップロードについて

    HTMLよりアップロード対象のテキストファイル(csv)パスが指定された場合、送られてくるcontent-typeがoctet-streamとなりますが正しいのでしょうか?何だかバイナリデータ扱いとなってしまい格納データがバイトコードになってしまいます・・・。multipart/form-dataでPOSTしているだけなのですが・・・

  • コマンドボタンでファイルの保存先を設定したい。

    C++ builder 2009を使用しています。現在、作成したバイナリデータをファイルとして出力する際に、ファイルの保存場所を設定するために、コマンドボタン1つとテキストボックス1つを用意して、コマンドボタンをおして、ファイルを保存するフォルダのパスを設定して、そのパスをテキストボックスに表示しておくということはどのようにすればよいでしょうか? SaveDialog1というのがありますが、これをつかうのでしょうか? どうぞ、ご教授よろしくお願い致します。

  • バイナリファイルのアップロードに関して

    今回質問させて頂くことに関連した問題を、現在MySQLのカテゴリで質問させていただいているのですが、 バイナリファイルをアップロードし、そのファイルのバイナリデータを変数($img)に格納し、それをDBに格納するという形を目指しています。しかし、DBにどうしても格納できません。もしやバイナリデータを変数に格納する時点で、既におかしいのかと思いまして、その部分についてこちらでご教授頂きたく書き込ませていただきました。 #!C:\Perl use CGI; use DBI; $PCMOJPATH='C:\パス名'; #ディレクトリ指定 my ($buffer); my $query = new CGI; $uniqid = time . "_" . $$; $newfile = "upload_$uniqid"; #ファイル名 print "Content-type: text/html\n\n"; print "<html><body>\n"; my $fH = $query->upload('filename'); my $mimetype = $query->uploadInfo($fH)->{'Content-Type'}; open (OUT, ">$PCMOJPATH/$newfile"); binmode (OUT); while(read($fH, $buffer, 1024)){ print OUT $buffer; $img .= $buffer;   #バイナリデータを$imgに格納 } close (OUT); close ($fH) if ($CGI::OS ne 'UNIX'); chmod (0666, "$PCMOJPATH/$newfile"); ------------------------- と書いているのですが、$imgにはバイナリデータがちゃんと入っていないのでしょうか?間違っているところがあれば、どのように直したらいいか教えてください。どうぞよろしくお願いします。

  • pdfファイルをテキストファイルに変換できるソフト

    インターネットなどでダウンロードしたpdfファイルで、 あるテキスト部分をドラックしてコピーして、ワードファイルやテキストファイルにペーストしても、そのコピーされません。 pdfファイル上では、そのテキスト部分はドラックすると、ドラックした部分が黒色に変わるので、そのテキスト部分は画像化はされていないと思うのですが、ワードファイルやテキストファイルにペーストしても、そのコピーされません。 なにかセキュリティ設定でもされているかもしれません。 そこで、このようなPDFファイルをワードファイルやテキストファイルに変換できるフリーソフトを教えてください。

  • 添付ファイルの中までテキスト検索できる掲示板

    様々なファイル(画像、エクセル、ワード、etc...)をアップできる掲示板を探しています。 エクセルやPDFなど、テキスト情報があるファイルの場合は、その中まで検索をかけられるようなものが良いのですが、いくつかダウンロードしてテストしてみたところ、索されるのは掲示板のタイトルや本文などのみで、添付されたファイル内までは検索をかけてくれないようです。 そのようなことができる掲示板プログラムをご存知ではないでしょうか? あるいは、そもそも不可能なことなのでしょうか? 他の方法をご存知の場合はそれもお知らせくださいますと助かります。

    • ベストアンサー
    • CGI
  • 画像とテキストが混在したPDFファイルをOCR認識させる方法

     1ページの中にテキストと画像が混在するWord文書をAcrobat8proでPDFに変換した文書のテキスト認識についの質問です。  この文書の画像部分をテキスト認識させるために、同ソフトのツールから「OCRを使用してテキスト認識」を実行させると、「画像にテキストデータが含まれているため認識できません」というエラーメッセージがでてしまいます。  スキャナーで取り込んだ画像データであれば、問題なく認識できるのですが、今ある大量のPDFファイルはすべてテキストと画像が混在するWordファイルを同ソフトでPDF変換したものです。そしてこのPDFの画像部分の文字をテキスト認識させたいのですが、このままではうまくいかずに困っています。かといって、すべて画像化するなどという手間はかけたくありません。  できるだけ手をかけずにこのPDFの画像部分をテキスト認識させる方法があれば教えて下さい。  なお、当方のOSはWindowsXPです。  以上よろしくお願いします。

  • ReadParseを使ってのバイナリファイルのアップロード

    ファイルをアップロードするCGIを作ろうと思い、以下のように書いてみました。そうしたところテキストファイルのアップロードには成功しましたが、バイナリファイルだとアップロード出来ても開けなかったり、画像が崩れてしまったりしてしまいました。 何故バイナリファイルだとアップロードが失敗してしまうのかわかりません。どこを直せば良いのでしょうか。 よろしくお願いします。 ----------------------------------------------- フォーム <FORM METHOD="POST" ENCTYPE="multipart/form-data" ACTION="xxx.pl"> <INPUT TYPE="file" NAME="file"> <INPUT TYPE="submit" VALUE="アップロード"> </FORM> ------------------------------------------------ xxx.pl &ReadParse(*in, *f_name, *f_type); $f_name{'file'}=~/([^\\\/]+)$/; $filename = $1; open(IN, ">$filename"); print IN $in{'file'}; close(IN);

    • ベストアンサー
    • CGI
  • リンクで画像ファイルやテキストファイルを表示

    友人からの依頼です。 ホームページでリンクをクリックすると画像やテキストを表示させたいのですが、良い場所はないでしょうか? ヤフーブリーフケースにテキストをアップロードしてそのURLのリンクをクリックしてもなぜか表示されないらしいです。 画像を置ける場所は多々あるようなのですが、テキストファイル(htmlファイル)も置けるところを探しています。 どうかお教え下さい。

専門家に質問してみよう