PHPでファイルアップロードのチェックやサイズを調べる方法

プログラミング
PHPでアップロードファイルの情報を見る場合に扱うことになる変数や、覚えておくと便利な関数を紹介していきます。スーパーグローバル変数である$_FILESを使用し、ここに連想配列の形で様々な情報が格納されていきますので、その扱い方を覚えておくと色んな場面で役に立つでしょう。
PHPでファイルアップロードのチェックやサイズを調べる方法

PHPを使うとWebアプリやサービスを制作することができますが、その際ファイルのアップロードを必要とすることも珍しくありません。そしてそのアップロードが正しく行われたのかどうか、またファイルの情報を取得したい場合もあります。ここではPHPを使ってこれらを実行するにはどうすればいいのか、その方法を紹介していきます。

PHPでファイルアップロードに関する情報をチェックできる


PHPはWebサイトやWebアプリの構築に向いている言語です。実際PHPを使って多くのサービスが提供されています。ユーザーとのやり取りでは目的などに応じて様々な情報が送受信されますが、ファイルをアップロードするということも珍しくありません。そしてその場合にはアップロードされた情報を取得し、その情報をもとに反応を返すという動作をしたいこともあります。

例えばファイル名を知りたい場合や、ファイルサイズを知りたいということもあるかと思います。PHPでは特別な変数等を使用していくことでアップロードしたファイルに関して色んな情報が取得できるようになっていますので、その基本的な使い方を知っておくと良いでしょう。

$_FILESとは

アップロードしたファイル情報を取得するために使用する変数が「$_FILES」です。これはPHPで定義済み変数とされている変数であり、つまりプログラムを組む人がわざわざ定義をしなくても初めから使えるようになっている変数になります。また$_FILESを別の言い方で「スーパーグローバル変数」とも呼びます。 $_FILES['name']といった具合に変数名に続けてファイル情報の種類を指定して使用します。具体的にどのような情報が取得できるのか、次項で紹介していきます。

$_FILESで取得できる情報


$_FILESでは主に「ファイル名」「ファイルタイプ」「一時ファイル名」「エラーコード」「ファイルサイズ」が取得できます。

  • ファイル名
    アップロードしたファイルの情報は$_FILESへ連想配列の形で格納されていき、 HTMLのinputタグで指定したnameを「uploadfile」とすれば、ファイル名は$_FILES['uploadfile']['name']の中に格納されることになります。

  • ファイルタイプ
    ファイル名が格納されているのと同様、ファイルのMIMEタイプも$_FILESの中に格納されています。MIMEタイプとはドキュメントの種類を表すもので、拡張子とは似て非なるものです。例えばテキストを含むものとして「text/html」など、画像を表すものとしては「image/jpeg」などがあり、これらの情報は$_FILES['uploadfile']['type']の中に情報が入っています。 ただしこの値は必ずしも正しいとは言えず、偽装されている可能性もあり注意が必要です。そこで、アップロードされたファイルのバイナリデータからできるだけ正しい値を読み取るという手法もあります。そしてそのためにはFileinfoという関数が効果的です。このファイルの種類識別の際にはこの関数も検討してみると良いでしょう。

  • 一時ファイル名
    $_FILES['uploadfile']['tmp_name']では、サーバー上で一時的に保存されるテンポラリファイル名が格納されています。

  • ファイルサイズ
    ファイルサイズの情報は$_FILES['uploadfile']['size']の中に格納されます。ただし格納された値はバイト単位になっていることには注意が必要です。

PHPでファイルアップロードの確認を行うプログラム例


前項で説明したアップロードしたファイルの各種情報、ファイル名やファイルサイズ以外にも調べたいことがあります。それはアップロードされているかどうかです。これをチェックするにはis_uploaded_file()関数を使用します。

if (is_uploaded_file($_FILES['uploadfile']['tmp_name'])) {
   echo "ファイル ". $_FILES['uploadfile']['name'] ." のアップロードに成功しました。\n";
   echo "その中身を表示します\n";
   readfile($_FILES['uploadfile']['tmp_name']);
} else {
   echo "おそらく何らかの攻撃を受けました。";
   echo "ファイル名 '". $_FILES['uploadfile']['tmp_name'] . "'.";
}

このプログラム例では、if文の中でアップロードがされていればtrue、アップロードがされていなければfalseを返すようになっています。そしてtrueの場合にはファイル名を表示してアップロードに成功したと表示させています。さらにその中身についても表示をしています。

一方で、一時ファイルに格納されていることが確認できなければ攻撃を受けたかもしれないとアナウンスするようになっています。 trueもしくはfalseを返された後の処理については自由にプログラムを組めばかまいませんが、基本的にはis_upload_file()関数はif文の中でこのように組み合わされて使います。

アップロードファイルへの操作にはmove_uploaded_file()関数というものもあります。この関数では第一引数でファイル名を指定し、そのファイルが有効にアップロードされているかどうか確認し、有効なファイルである場合には第二引数で指定したファイル名に移動させるという処理を行います。

そしてこの関数は、処理に成功するとtrueを返しますが、第一引数で指定したものが有効なアップロードファイルでなければ処理は行われずにfalseを返します。さらに、アップロードファイルが有効であったとしても何かしらの問題によってファイルの移動ができなければこの場合でもやはりfalseを返し、警告が出力されます。また、コピー先のファイルがすでに存在していると上書きされてしまいます。この関数を使うときには注意しましょう。

ファイルのアップロードでは、さらにセキュリティ面への配慮も必要です。ユーザーが自由にファイル名を指定できる場合、そのファイルをアップロードした際に攻撃を受ける可能性もあります。サーバー上でアップロードされたファイルを操作する場合にはリネームするなどの対策も施すと良いでしょう。

まとめ

PHPでアップロードしたファイルの情報を確認したい場合などには関数や特別な変数を用いるとそのチェックができます。具体的にはスーパーグローバル変数である$_FILESを使うということ、そしてこの変数の中には連想配列の形式で「ファイル名」や「ファイルタイプ」、「一時ファイル名」、「ファイルサイズ」などが格納されているということを覚えておくといいでしょう。

また、アップロード自体ができているのか確認するためにはis_uploaded_file()関数を使いif文と組み合わせるとアップロードが成功した場合と失敗している場合とで処理を分けることができるようになります。またmove_uploaded_file()関数ではファイルのコピーを行うこともできます。ぜひ、これらの関数や変数を使いこなして実用的なプログラムを作成していきましょう。


この記事のキーワードに関する勉強会・イベントを探す

TECH PLAYでは、ITエンジニア向けの勉強会・イベント情報を提供しています。
興味のある方はぜひご参加ください。


おすすめのコラム