はじめに
ブラウザのフォームからファイルを2つアップロードしたとき、PHPで $_FILES
を var_dump()
してみると、2つの配列が並んで表示されます。これが正しい挙動なのか?混乱しやすいポイントを整理しておきましょう。
目次
🧩 フォームのHTML
<form enctype="multipart/form-data" action="./p110.php" method="POST">
このファイルをアップロード:<input type="file" name="userfile"><br>
このファイルをアップロード:<input type="file" name="userfile2"><br>
<button>ファイルを送信</button>
</form>
enctype="multipart/form-data"
が指定されている点が重要です。これがないとファイルデータが送信されません。
🧠 サーバー側の受け取り
<?php
declare(strict_types=1);
error_reporting(-1);
echo "<pre>";
var_dump($_FILES);
var_dump($_POST);
これをブラウザから実行すると、次のような出力になります👇
💻 実行結果
array(2) {
["userfile"]=>
array(5) {
["name"]=>
string(17) "untitled text.txt"
["type"]=>
string(10) "text/plain"
["tmp_name"]=>
string(14) "/tmp/phpksTdjU"
["error"]=>
int(0)
["size"]=>
int(35)
}
["userfile2"]=>
array(5) {
["name"]=>
string(17) "untitled text.txt"
["type"]=>
string(10) "text/plain"
["tmp_name"]=>
string(14) "/tmp/phpObV6YG"
["error"]=>
int(0)
["size"]=>
int(35)
}
}
array(0) {
}
✅ これは「正しい」挙動!
$_FILES
の中には、ファイルごとに独立した情報が入ります。
$_FILES = [
"フィールド名" => [
"name" => ファイル名,
"type" => MIMEタイプ,
"tmp_name" => 一時ファイルパス,
"error" => エラーコード,
"size" => サイズ(バイト)
]
];
今回の場合:
┌──────────────────────────────┐
│ $_FILES │
│ ├─ userfile → ファイル1情報 │
│ └─ userfile2 → ファイル2情報 │
└──────────────────────────────┘
※ tmp_name
はリクエストごとにランダム生成されるため、毎回異なるのが正しい動作です。
💡なぜ $_POST は空なの?
フォーム内にはテキストやhiddenなどの「通常のPOSTデータ」がないため、
$_POST は空配列(array(0) {})になります。これも正常です。
⚡️応用:同じnameで複数ファイルを送る場合
もし同じname
属性で複数ファイルを選ばせたいなら、こう書きます👇
<input type="file" name="userfile[]" multiple>
するとPHP側では以下のように受け取れます。
$_FILES['userfile']['name'][0]
$_FILES['userfile']['name'][1]
つまり、同じフィールド名の中で配列化される という違いです。
🧭 まとめ
項目 | 内容 |
---|---|
$_FILES | ファイル情報を格納するスーパーグローバル変数 |
nameが異なる場合 | フィールド名ごとに配列が分かれる |
nameが同じ場合 (userfile[] ) | 配列の中に複数ファイル情報が入る |
tmp_name | 一時ファイルのパス。毎回異なるのが正しい |
$_POST | 通常データがない場合は空になる |
この内容はPHP8上級試験の 「ファイルアップロード」セクション でよく問われる定番ポイントです。
特に「同じnameと異なるnameの違い」は混同されやすいので、手を動かして確かめておきましょう。