PHPプログラミング

最終更新日:
公開日:

レシピ

スーパーグローバル変数

アップロードしたファイルの情報を取得する:$_FILES

PHPでファイルアップロードを行う際にはファイル情報がスーパーグローバル変数の「$_FILES」に格納されます。今回はこちらの変数の内容や注意点と、関連する関数を使ったファイル情報の取得方法について解説します。

この記事のポイント

  • ファイルアップロード時の$_FILESの中身を知る
  • アップロードされたファイルのMIMEタイプを正しく判定する

目次

$_FILESとは

PHPのスーパーグローバル変数$_FILESはアップロードされたファイル情報が格納される変数として用意されています。
input要素で選択されたファイルをアップロードする時に、この変数へファイルの仮情報が格納されます。

$_FILESの中身

変数名内容
nameアップロードされたファイル名
typeアップロードされたファイルの形式(MIMEタイプ)
tmp_nameサーバーへ仮アップロードされたディレクトリとファイル名
errorエラー情報
sizeファイルサイズ(単位はバイト)

試しにファイルアップロードするソースを用意し、これらの情報を確認してみましょう。

PHP コード例

<?php
var_dump($_FILES);
?>

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>テスト</title>
</head>
<body>
  <form method="post" action="" enctype="multipart/form-data">
    <input type="file" name="upload_file">
    <div>
      <input type="submit" name="btn_submit" value="送信">
    </div>
  </form>
</body>
</html>

上記コードを最初に開いた時の表示はこちら。
まだファイルは選択されていないので$_FILESは空です。

実行前のページ
表示結果 その1

「ファイルを選択」からアップロードするファイルを選択し、下の「送信」ボタンを押すと次のような表示になります。
今回は試しにjpeg画像を選択しています。

アップロード実行後。ファイル情報が出力される
表示結果 その2

アップロードしたjpeg画像のファイル情報が出力されました。

upload_file」はinput要素name属性です。
複数のファイルをアップロードした時にも、このname属性で取得したいファイル情報のみを取得することが可能です。

ファイル情報を詳しく見ていくと、元ファイル名は「home.jpg」、ファイル形式は「image/jpeg」、ファイルサイズは270,000バイト(270KB)となっています。
また、「tmp_name」の場所へ一時的にアップロードされていることも分かります。

Note

自分だけかもしれませんが、$_FILESの末尾の「S」をよく忘れます。
S」なしの$_FILEだと全く別の配列を扱うことになり、当然ファイル情報も参照することができません。

$_FILESの「type」は信用できない

スーパーグローバルの$_FILESに含まれる「type」にはファイル形式(MIMEタイプ)が格納されますが、実は拡張子から判断しているだけなので簡単に偽装できてしまいます。
例えば、次のようなJPEGファイルがあるとします。

確認用JPEGファイル

このファイルの拡張子を「png」へ変更してアップロードしてみます。
拡張子を変更しただけなので、本来はJPEG形式と表示して欲しいところですが…

拡張子をPNG形式へ変更
本来のファイル形式が出力されない
アップロード実行結果

拡張子のまま、PNG形式と出力されてしまいました。
拡張子を「.gif」や「.zip」に変更しても同じように、それぞれのファイル形式として出力されてしまいます。
これでは仮に「JPEG形式のみ受け付けたい」と言った場合にうまく対応ができません。

この問題については、グラフィック関連のGDライブラリ、またはFileInfoライブラリの関数を使うことで解決することができます。

GDライブラリのgetimagesize関数

getimagesize関数を使って、ファイル形式を確認してみます。赤いコードが追加したコードです。

PHP コード例

<?php
var_dump($_FILES);
var_dump( getimagesize($_FILES['upload_file']['tmp_name']));
?>

// 先ほどのHTMLが続く
getimagesize関数の実行結果
実行結果

出力された情報を比較すると一目瞭然です。
getimagesize関数ではしっかりと本来の形式が取得できていることが分かります。
あわせて画像の縦幅や横幅も取得できるので非常に便利な関数です。

FileInfoライブラリのmime_content_type関数

次に、FileInfoライブラリのmime_content_type関数をみていきます。

PHP コード例

<?php
var_dump($_FILES);
var_dump( mime_content_type($_FILES['upload_file']['tmp_name']));
?>

// 先ほどのHTMLが続く
mime_content_type関数の実行結果
実行結果

シンプルに本来のMIMEタイプを取得することができました。

ファイルの正確なMIMEタイプを取得する方法を2つ紹介してきましたが、どちらを使っても特に問題ありません。
使い分けるポイントはMIMEタイプ以外の情報が必要かだと思います。
本当にMIMEタイプのみを取得したければmime_content_type関数を、画像の横幅と縦幅が他の場所で必要になる場合はgetimagesize関数を使うようにしましょう。

こちらの記事は役に立ちましたか?

ありがとうございます。
もしよろしければ、あわせてフィードバックや要望などをご入力ください。

コメントありがとうございます!
運営の参考にさせていただきます。