ホーム › エラー解決 › PHP › Undefined array key
PHP ERROR

PHP Undefined array key の解決法

配列に存在しないキーを参照したときの警告です。isset()やnull合体演算子で防げます。

このエラーメッセージ

Warning: Undefined array key "age"

原因

❌ エラーになるコード

NG
<?php
$user = ["name" => "Taro"];
echo $user["age"];

✅ 修正したコード

OK
<?php
$user = ["name" => "Taro"];
echo $user["age"] ?? "未設定";   // null合体演算子
if (isset($user["age"])) {
    echo $user["age"];
}
▶ 修正済みコードを実行エディタで開く
progoのPHP実行環境(インストール不要・登録不要)でその場で動作を確認できます。

解決のポイント

存在しないかもしれないキーはnull合体演算子??で既定値を指定します。$user["age"] ?? "未設定"ならキーが無くても警告になりません。isset()やarray_key_exists()で事前確認するのも有効です。

「Undefined array key 0」「1」— 数値キーの場合

キー名が"age"のような文字列ではなく0や1の数字で出るときは、分割・抽出の結果が期待した件数に足りていないのがほぼ原因です。

NG
<?php
$line = "progo";              // カンマが無い行
$cols = explode(",", $line);
echo $cols[1];                // Warning: Undefined array key 1
OK
<?php
$line = "progo";
$cols = explode(",", $line);
echo $cols[1] ?? "(2列目なし)";

// 件数を確かめてから使うとより安全
if (count($cols) >= 2) {
    echo $cols[1];
}
▶ このコードを実行エディタで開く
explodeの結果が何件返るかをその場で確認できます。

Undefined index との違い(PHP 8で文言が変わった)

同じ状況でも、PHPのバージョンによってメッセージと深刻度が変わります。古い記事の「Undefined index」と今の「Undefined array key」は同じ現象です。

バージョンメッセージレベル
PHP 7.x以前Notice: Undefined index: ageNotice(表示されないことも多い)
PHP 8.0以降Warning: Undefined array key "age"Warning(既定で表示される)

「PHP 8に上げたら急にWarningが大量に出た」のは、もともとあったバグが見えるようになっただけです。警告を抑制せず、キーの有無を確認するコードに直すのが正しい対応です。なお変数そのものが無い場合はUndefined variableになります。

$_POST / $_GET / $_SESSION での定番対処

実務でこのWarningが出る場所の大半はフォーム入力です。送られてこない可能性を前提に書きます。チェックボックスは未チェックだとキー自体が送られない点に注意してください。

OK
<?php
// 既定値つきで受け取る
$name  = $_POST["name"] ?? "";
$agree = isset($_POST["agree"]);        // チェックボックスは有無で判定
$page  = (int)($_GET["page"] ?? 1);     // 数値は型変換もセットで

// 空文字も既定値にしたいときは ?: を併用
$sort = ($_GET["sort"] ?? "") ?: "new";

// 必須項目はまとめて検証する
$required = ["name", "email"];
$missing  = array_diff($required, array_keys($_POST));
if ($missing) {
    echo "未入力: " . implode(", ", $missing);
}

?? / ?: / isset / empty / array_key_exists の使い分け

書き方キーが無い値がnull値が"" / 0
$a["k"] ?? "既定"既定値(警告なし)既定値そのまま使う
isset($a["k"])falsefalsetrue
array_key_exists("k", $a)falsetruetrue
empty($a["k"])true(警告なし)truetrue(注意)

empty()は"0"や0も「空」と判定するため、数量や件数の判定に使うと不具合になります。キーの有無を見たいだけなら??かisset()、値がnullでもキーの存在を知りたいならarray_key_exists()が正解です。

ネストした配列を安全に取り出す

APIのJSONや設定配列のように階層が深い場合、??は途中の階層が無くても警告を出さずに済みます。

OK
<?php
$json = '{"user":{"profile":{"name":"Taro"}}}';
$data = json_decode($json, true);

// 途中の階層が無くても警告なし
$name = $data["user"]["profile"]["name"] ?? "名無し";
$city = $data["user"]["address"]["city"] ?? "未登録";
echo $name, " / ", $city;

デバッグ時はvar_dump($data);やprint_r(array_keys($data));で実際に入っているキーを確認するのが近道です。キー名の全角・半角、前後の空白、大文字小文字の違いもよくある原因です。

警告を非表示にする方法(非推奨)

error_reporting(E_ALL & ~E_WARNING);や@$user["age"]で警告は消せますが、原因は残ったままで、後により深刻な不具合として現れます。本番環境では画面に出さない設定(display_errors=Off+ログ出力)にしつつ、コード側は??で直すのが正しい運用です。

よくある質問

issetとarray_key_existsの違いは?
値がnullのキーはissetがfalse、array_key_existsはtrueを返します。キーの存在そのものを知りたいときはarray_key_existsを使ってください。
?? はどのバージョンから?
PHP 7.0以降で使えます。$a["k"] ?? "既定" と書けばキーが無くても警告になりません。
Undefined array key 0 と出ます
explodeやpreg_matchの結果が期待した件数に足りていません。区切り文字が無い行やマッチしなかったケースを想定し、?? かcount()で件数を確認してください。
Undefined index との違いは?
同じ現象です。PHP 7.xまではNotice: Undefined index、PHP 8.0以降はWarning: Undefined array keyという表記になりました。
PHP 8にしたら警告が大量に出ました
もともと存在していた問題がNoticeからWarningに格上げされ、既定で表示されるようになったためです。抑制せず ?? やisset()でキーの有無を扱うよう直してください。
チェックボックスが Undefined array key になります
未チェックのチェックボックスはキー自体が送信されません。$_POST["agree"] ?? "" か isset($_POST["agree"]) で判定してください。
emptyで判定してもいい?
emptyは0や"0"も空と判定するため、数量・件数の判定には向きません。キーの有無だけなら ?? かisset()を使ってください。
警告を消すだけではだめ?
@演算子やerror_reportingで消せますが原因は残ります。本番はdisplay_errors=Offでログに残し、コードは ?? で直すのが正しい対応です。