PHPプログラミング

レシピ

スーパーグローバル変数

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

ファイルのアップロード処理を行う際に、必ず必要になるファイル情報。PHPはアップロードファイルの情報は全てスーパーグローバル「$_FILES」に格納されます。

この記事のポイント

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

目次

$_FILESとは

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

$_FILESの中身

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

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

コード

<?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>

表示結果 その1

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

実行前のページ

「ファイルを選択」からアップロードするファイルを選択し、下の「送信」ボタンを押すと次のような表示になります。
今回は試しに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
var_dump($_FILES);
var_dump( getimagesize($_FILES['upload_file']['tmp_name']));
?>

// 先ほどのHTMLが続く

実行結果

getimagesize関数の実行結果

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

FileInfoライブラリのmime_content_type関数

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

コード

<?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関数を使うようにしましょう。

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

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

ありがとうございます。
コメントを送信しました。