質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

4082閲覧

PHPでアップロードしたファイルの確認方法について教えてください。

7968

総合スコア253

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2017/04/18 01:45

編集2017/04/18 08:43

現在、ファイルのアップロードについて網羅的に調べています。

私が調べた限り、アップロードしたファイルのMIMEタイプを確認できる関数まはたクラスは5つありました。

それぞれ、バージョンまたは拡張の有無によって使えるか変わるので、2つのXAMPP環境で動作を確認しました。

それぞれの結果が下記です。

関数XAMPP 1.6.1(PHP 5.2.1)XAMPP 1.7.3(PHP 5.3.1)
mime_content_type×
finfo クラス×
fileinfo 関数×
getimagesize
exif_imagetype

ファイルをサーバーに保存したくないので move_uploaded_file は、なるべく使いたくないと仮定します。
(ユーザーが直接アクセスできないディレクトリに保存すればよいだけですが、今回はなるべく使わない方法を聞きたいです)

2つ質問がございます。

【質問1】テンポラリファイルのMIMEタイプは、どの関数またはクラスで確認できますか?

私の確認の仕方に問題があるかもしれませんが、下記のようにfileinfo関数では、テンポラリファイルのMIMEタイプを確認できました。

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>PHP</title> </head> <body> <form method="post" enctype="multipart/form-data"> <p>Pictures: <input type="file" name="pictures"> <input type="submit" value="送信"> </p> </form> <?php if(isset($_FILES['pictures'])) { $tmp_file_data = file_get_contents($_FILES['pictures']['tmp_name']); $finfo = finfo_open(FILEINFO_MIME); $mime_type = finfo_buffer($finfo, $tmp_file_data); finfo_close($finfo); echo '<p>fileinfo 関数の値:' . $mime_type . '</p>'; } ?> </body> </html>

試してはないですが、finfoクラスでも同様に確認できるかと思います。

他の関数については、$_FILES['pictures']['tmp_name'] を指定してもエラーが表示されます。
これらは、move_uploaded_file でファイルを移動すれば、問題なく確認できましたが、テンポラリファイルの状態では確認できませんでした。

テンポラリファイルのMIMEタイプを確認できるのは、fileinfo関数またはfinfoクラスだけですか?

【質問2】PHP5.2環境ではテンポラリファイルのMIMEタイプをどのように確認していたのでしょうか?

私が5.2環境で試したときは、getimagesize と exif_imagetype しか動作しませんでした。
私の検証結果が正しければ、これらの関数ではテンポラリファイルのMIMEタイプは確認できないです。
PHP5.2を使っていた時代でもファイルのアップロードはしていたと思います。
どのようにMIMEタイプを確認していたのでしょうか?

考えられる方法(※調べた結果なので試してません)

  1. Fileinfoは、PHP5.3まではPECL拡張なので、追加して確認する
  2. fileコマンドで確認する
  3. file_get_contents + bin2hex でバイナリデータを取得して、自前で用意したマジックバイトシーケンスと一致するか確認する
  4. テンポラリファイルの状態で確認するのは諦め、move_upload_file + getimagesize or exif_imagetype で確認する

ご存じの方いれば、教えてください((_ _ (´ω` )ペコ

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2017/04/18 02:26

画像を保存しないのにアップロードさせる意味はあるのでしょうか?mime自体あくまで目安なのであまり深く考えてもしかたないと思います
7968

2017/04/18 03:54 編集

掲示板のような場合だと保存する必要はあるけど、添付メールフォームのような場合だと保存は必要ないのかなと思いました。 これらの関数・クラスは、ファイル自体のマジックナンバーでMIMEを判定しているかと思います(PHPのコアファイルを読むスキルはないため、勝手な憶測)。 ここ(http://qiita.com/rana_kualu/items/aec5c3d93e9eb2c8f0ba)に記載されている通り、簡単に騙すことは可能ですが、マジックナンバーからMIMEを判定し、リクエストメッセージのMIMEと一致するか確認したり、そこから拡張子を決めたりすることになるのかと思い、質問しました。
shi_ue

2017/04/18 08:52

なぜ、こんなに古いPHPのバージョンで検証しているんでしょうか?
7968

2017/04/18 10:50 編集

えーと、半分は興味本位で、半分はムキーとなって調べてます。 PHPでアップロードされたファイルのMIMEタイプを確認する方法を調べたら上述した通り、5つありました。 何がどのように違うのか、ググっても一覧で説明しているところがなく、これからファイルのアップロードについて学びたいと考えている人にはわからなくね?とムキーとなって、網羅的に調べてまとめてます。 PHP5.2と5.3の環境で検証しているのは、5.3でMimetype拡張モジュールが廃止され、新たにFileinfo拡張モジュールが追加されたためです。
guest

回答2

0

ベストアンサー

実際実務でどう使われていたかは知らないのですが、
参考:PHPでMIME-Typeを判定する方法

$path = $_FILES['myfile']['tmp_name'];
$mime = shell_exec('file -bi '.escapeshellcmd($path));

考えられる方法2でおっしゃられているように、環境にもよりますが、
PHPからシェルのコマンドを叩いて取得するのが妥当なんじゃないかと思います。

投稿2017/04/18 12:35

ebita

総合スコア28

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

7968

2017/04/18 14:29

参考サイトありがとうございます。 やはり、そうですよね。 質問2に関しては、方法1か方法2かなと思います。
ebita

2017/04/19 03:59

ちなみに質問1につきまして、 自分のLinux PHP5.3の環境ではmime_content_typeを使用してテンポラリファイルのmimetypeが取得できています。 [HTML] <form id="hoge" action="hoge.php" method="post" enctype="multipart/form-data"> <input type="file" id="sendfile" name="sendfile" accept="image/*" /> </from> [PHP] $mimetype = mime_content_type($_FILES['sendfile']['tmp_name']); error_log($mimetype); >image/jpeg 環境や設定で挙動が違うのでしょうね。 全く回答にはなっておりませんが、参考程度にと思いコメントさせて頂きました。
7968

2017/04/19 04:17 編集

おお!mime_content_typeで取得できるんですね。 mime_content_typeは、PHP5.3から finfo や fileinfo と同じFileinfo拡張モジュールを使っているらしいので、拡張モジュールが入っていて有効になっていれば、テンポラリファイルのmimetypeも取得できるんですね。 参考になりました。ありがとうございます。
guest

0

お陰様で理解できました。
ありがとうございます。
とりあえず、ファイルアップロードに関してまとめた記事をQiitaに投稿にしました。
この質問を見た方のために、リンクを貼っておきます。


【質問1】について

改めて確認したところ、getimagesizeexif_imagetype もテンポラリファイルの状態でMIMEタイプを確認できました。

私の確認の仕方に問題があり、move_uploaded_file でテンポラリファイルを移動した後に getimagesize($_FILES['upfile']['tmp_name'])exif_imagetype($_FILES['upfile']['tmp_name']) を記述していたの原因でした、すいません><

投稿2017/04/27 05:14

編集2017/04/27 08:31
7968

総合スコア253

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問