PHPでのファイルアップロードとエラーチェックの方法

  • このエントリーをはてなブックマークに追加
  • Pocket

スポンサードリンク

PHPでファイルをアップロードするシンプルな方法から、エラーチェックや容量制限を設定する方法も併せてご紹介します。

 

ファイル構成

本記事は以下の2つのファイル構成を想定しています。

  1. index.html…フォームを設置したHTMLファイル
  2. upload.php…フォームの遷移先でアップロード処理をするPHPファイル

シンプルなファイルアップロード

まずは、エラーチェックをしない必要最小限のファイルアップロードです。

サンプルコード

index.html

upload.php

これだけで実際にファイルのアップロードができます。

ファイルアップロードの流れ

ファイルアップロードは以下のような流れで動作します。

  1. ファイルアップロードフォームでアップロード
  2. サーバーの一時フォルダに一旦保管
  3. move_uploaded_file()で指定のパスに移動

ファイルアップロードフォームでUPされたファイルは、サーバーのテンポラリフォルダに一旦保管されます。

そしてmove_uploaded_file()で指定したパスにファイルを移動させます。

ファイルアップロード用フォーム

HTMLでファイルアップロードを実現するには以下のポイントがあります。

  1. formタグのenctypemultipart/form-dataを設定
    <form action=”upload.php” method=”post” enctype=”multipart/form-data”>
  2. input typeにはfileを指定
    <input type=”file” name=”upload”>

move_uploaded_file関数の構文

アップロードされたファイルを新しい場所に移動させます。

move_uploaded_file ( アップロードされたファイル名 , 移動先パス/ファイル名 )

グローバル変数「$_FILES」

上記サンプルコードにある$_FILES['upload']['tmp_name']はアップロードされたファイルの情報が格納されたグローバル変数です。

以下のような構文になっています。

$_FILES [ アップロードフォームのinput name値 ] [ アップロードされたファイル情報の項目 ]

最初の[]にはHTMLアップロードフォームのinput属性のname値が設定されます。

2番目の[]にはアップロードされたファイル情報の項目が入ります。

ちなみに$_FILESの中身は以下のような連想配列になっています。

Array(
[name] => memo.txt
[type] => text/plain
[tmp_name] => /var/tmp/php7UNOJY
[error] => 0
[size] => 45
)

配列で取得した各項目は以下のような内容になります。

項目内容
name元ファイル名
typeファイルタイプ
tmp_nameサーバーに一時保管されたファイル名
errorエラーコード
sizeファイルのバイト数

上記項目を使って、エラーチェックなどを行います。

エラーコードは0ならアップロード成功で、1468は以下のようなエラーになります。

コードエラー定数説明
0UPLOAD_ERR_OKエラーなし
1UPLOAD_ERR_INI_SIZEphp.iniのupload_max_filesizeのサイズを超えている
2UPLOAD_ERR_FORM_SIZEHTMLフォームで指定された MAX_FILE_SIZE を超えている
3UPLOAD_ERR_PARTIAL一部のみしかアップロードされていない
4UPLOAD_ERR_NO_FILEアップロードされなかった
6UPLOAD_ERR_NO_TMP_DIRサーバー一時保管フォルダがない
7UPLOAD_ERR_CANT_WRITEディスクへの書き込みに失敗
8UPLOAD_ERR_EXTENSIONPHPの拡張モジュールがアップロードを中止した

さまざまなエラーチェック

エラーチェックはセキュリティやパフォーマンス的にも必須でしょう。

追求すればきりがありませんが、ここでは最低限のエラーチェックを追加したサンプルをご紹介します。

サンプルコード

index.html

upload.php

上記のように$_FILESの値を使って、簡単ですがエラーチェックをしてみました。

丸囲み数字のエラーチェックを以下で解説します。

①POSTリクエストによるページ遷移かチェック

if ($_SERVER[‘REQUEST_METHOD’] === ‘POST’) {

サーバー変数でPOSTかどうかをチェックしています。

upload.phpに直接アクセスするのを防ぎます。

参考:サーバー変数一覧と実用例

②ファイル制限超過チェック

if ($_FILES[‘upload’][‘error’] === 2) {

HTMLフォームで指定されたMAX_FILE_SIZEを超えた場合、エラーコード 2 が返されます。

ちなみに、以下のようなフォームの要素を1つ追加しています。

<input type=”hidden” name=”MAX_FILE_SIZE” value=”1000″>

隠し要素に以下の値を設定すると、HTML側でファイルサイズの制限をすることができます。

  1. name値にMAX_FILE_SIZEを設定する
  2. value値にファイルサイズの上限値をバイト数で指定する

注意:MAX_FILE_SIZE は input type=”file” 要素より前に設定しないと動作しません。

③ファイル存在チェック

} elseif ($_FILES[‘upload’][‘size’] === 0) {

$_FILES['upload']['size']の値が0だった場合、ファイルが空(アップロードするファイルが存在しない)と判定しています。

アップロードするファイルを選択しなさい!とメッセージを出します。

④ファイルタイプチェック

} elseif ($_FILES[‘upload’][‘type’] !== ‘text/plain’) {

ファイルタイプがテキストファイル以外をエラー判定しています。

画像ファイル以外をエラーにしたりなど、よく使われます。

参考:PHPでif文

他にも、ファイル名をより複雑にすることで、ファイル名の重複を避けたり、セキュリティ上のリスク回避にも繋がります。

以下の記事でご紹介しています。

参考:mt_randでファイル名をランダムに生成

 

ここでは割愛いたしますが、実装する際にはセキュリティ上の観点からも、エラーチェックはより厳重にする必要があります。

基本が分かったら、より実践的なプログラムにステップアップしてみましょう。

php.iniによる制限

HTML側でMAX_FILE_SIZEを設定した場合でも、ブラウザの設定を出し抜くことは簡単です。

注意: ブラウザ側でこの最大値を出し抜くのは簡単なことなので、この機能を信頼して、 これより大きなサイズのファイルがブロックされることを前提にしてはいけません。 しかし、PHP 側の最大サイズの設定を欺くことはできません。

出典:PHPマニュアル

上記にもあるように、PHP側でもphp.iniでサイズ制限などの設定があります。

(多くのサーバーではすでにデフォルトで制限されているかと思います。)

以下の項目が関係してくるので適切に設定しましょう。

項目説明初期値
post_max_sizePOSTする際のサイズ上限値。upload_max_filesize以上の値を設定する。8M
upload_max_filesizeアップロード時のファイルサイズ制限値で、post_max_sizeの値以下で設定する。MAX_FILE_SIZEはこの値以上は設定できない。2M
memory_limitアップロード時の消費メモリ上限値。大きなファイルをアップロードする際は増やす。128M
max_execution_timeアップロード時の最大実行時間。あまり大きな値を設定すると、サーバーに負荷がかかりメモリ不足となることもある。60(秒)
max_file_uploadsアップロードできるファイル数の上限値。この数以上は一度にアップロードできない。20

ファイルのアップロードの初歩的なところをご紹介しましたが、まだまだ奥が深い領域なので、別の機会にご紹介していきたいと思います。

スポンサードリンク

  • このエントリーをはてなブックマークに追加
  • Pocket

コメント

  1. NANTO より:

    とても分かりやすかったです。ありがとうございます!

    1. flatFlag より:

      そう言っていただけるととても嬉しいです。ありがとうございます。
      これからも分かりやすさを第一に記事作成に取り組んでまいります。

flatFlag へ返信する コメントをキャンセル

*