[PHP] $_FILES[hoge]がundefinedになる問題
3 min read
はっきりとした理由は結局分かってはないんだけれど…。
状況
1GBのファイルをアップロードできるアプリ。ファイルサイズが1GB以上の場合はエラーメッセージを返却する作り。 しかし、1.2GBのファイルをアップロードしたときに $_FILES['hoge']が undefined になってしまった。仮説
memory_limit, post_max_size, upload_max_filesize のいずれか、もしくは全ての設定値が1.2GBに対して足りないため、$_FILES['hoge'] が作られないのではないか。(このとき、php.ini の設定は1GBのアップロードに最適化させていた)php.ini の設定
1GBアップロードの想定はこんな感じで設定してた。memory_limit = 1230M post_max_size = 1130M upload_max_filesize = 1024M
2GB のアップロードに対応できる想定の値に変更。
memory_limit = 2460M post_max_size = 2260M upload_max_filesize = 2048M
検証結果
2GBまで対応させることで1.2GBのアップロードで問題が起きなくなった。 1.2GBではなく2.2GBをアップロードすると同様の問題が発生するように想定できる。イタチごっこなので対応したい。対応
「PHP - ファイルアップロードの例外処理はこれぐらいしないと気が済まない - Qiita」から丸パクリみたいな形になって恐縮だが、おおむね以下のような形で実装した。- $_FILES['upfile'] が存在するか確認
- $_FILES['upfile']['error'] の内容を確認 → 致命的っぽいエラーは Exception を投げる
- $_FILES['upfile']['size'] で定義した上限値との比較
try {
if (
!isset($_FILES['upfile']['error']) ||
!is_int($_FILES['upfile']['error'])
) {
throw new RuntimeException('パラメータが不正です');
}
switch ($_FILES['upfile']['error']) {
case UPLOAD_ERR_OK: // OK
break;
case UPLOAD_ERR_NO_FILE: // ファイル未選択
throw new RuntimeException('ファイルが選択されていません');
case UPLOAD_ERR_INI_SIZE: // php.ini定義の最大サイズ超過
case UPLOAD_ERR_FORM_SIZE: // フォーム定義の最大サイズ超過
throw new RuntimeException('ファイルサイズが大きすぎます');
default:
throw new RuntimeException('その他のエラーが発生しました');
}
// ここで定義するサイズ上限のオーバーチェック
if ($_FILES['upfile']['size'] > 1000000) {
$message = 'ファイルサイズが大きすぎます。';
}
} catch (Exception $e) {
$message = $e->getMessage();
}
php.ini で設定した値の上限を超えた場合、つまり今回のように $_FILES['hoge'] が見つからない場合は、以下の条件で拾う事ができるはず。
!isset($_FILES['upfile']['error'])