概要
ファイルアップロードは「Web で唯一、バイナリを Body に乗せる仕組み」。普通のフォーム送信 (application/x-www-form-urlencoded) では Body に key=value の文字列しか乗らないが、画像など ファイルを送るときは違うエンコーディング が要る。それが <form enctype="multipart/form-data"> で指定する multipart/form-data。Body を境界線で区切り、各セクションにヘッダ + 中身 (バイナリも OK) を並べる HTTP の特別な書式。
PHP 側にはアップロード情報が $_FILES 連想配列 で届く。$_FILES['avatar']['name'] (元のファイル名)、['tmp_name'] (PHP が一時保存した場所)、['size']、['type'] (ブラウザ自己申告 MIME)、['error'] という構造。永続化は move_uploaded_file($tmp, $dest) を使うのが原則 (アップロード由来かを検証する保護付き)。
絶対に手を抜けないのが セキュリティ。「拡張子 / MIME / サイズ」をサーバー側で必ず再検証する。$_FILES['type'] はブラウザの自己申告で信用できないので、finfo_file() で実体から MIME を判定するのが正解。.php など実行可能な拡張子をアップロードさせるのは致命的で、保存ディレクトリは public 領域から分離 し、ホワイトリストで拡張子を絞る。CLI 採点では再現できないため、本章は 概念とドリル無しの座学 に振り切る。
学習目標
- HTML フォームのアップロード送信に必要な
enctype="multipart/form-data"を言える - PHP 側に届く
$_FILESの構造 (name/tmp_name/size/type/error) を読める move_uploaded_file($tmp, $dest)で 一時ファイルを 保存先に移す 流れが分かる- アップロード処理での セキュリティ最低限 (拡張子ホワイトリスト / サイズ上限 / 保存ディレクトリの分離) を言える
ドリル
このチャプターにドリルはありません。
理由: ファイルアップロードは HTML フォーム → HTTP multipart/form-data → PHP の $_FILES という Web ランタイム前提の機能で、本コースの CLI 採点ランナーでは再現できない。$_FILES を CLI で擬似的に埋めるスタブは書けるが、move_uploaded_file が 「本物のアップロード由来のファイルしか動かさない」 ように保護されているため、意味のあるドリルにならない。
代わりに 「概念と落とし穴」 をスライドで頭に入れ、実機 (php -S + ブラウザ) で 任意で試す案内とする。
本物の体験 (任意)
php -S でローカルサーバーを立ち上げてブラウザから試すと、5 分で全体像が掴める。スライド末尾の最小サンプル (form.html + upload.php) を写経して、ブラウザで localhost:8000/form.html を開いて画像を 1 枚アップしてみると分かりやすい。