ブログ
【PHP】Undefined offset: 未定義の配列参照エラーについて
こんにちは!
皆さんはPHPで配列を扱っている際に、Undefined offset
のエラーが返ってきたご経験はありますでしょうか。
私は絶賛そのエラーに遭遇したばかり! …なのですが、PHPのバージョンによってはエラーの内容が異なってくるため、あまり記憶に新しくないよ、という方もいらっしゃるかもしれません。
今回は、Undefined offset
が発生する原因に加えて、PHPのバージョンごとに異なる挙動の差についてまとめてみました。
目次
『Undefined offset』の原因
array 型の変数に対して、『存在しないインデックスの要素』にアクセスしようとしているため発生します。
$test_array = array("test0", "test1"); // array型
var_dump($test_array[2]);
出力結果(PHP 7.4.0 の場合)
Notice: Undefined offset: 2
上の例では、配列のインデックスの0・1はそれぞれ値が定義されていますが、2は未定義のためエラーとなっています。
ちなみに、配列のキーについては型キャストが行われているようで、以下どちらの記述でも、int 型として扱われるようです👀
var_dump($test_array[2]);
var_dump($test_array["2"]);
key は、整数 または 文字列です。
さらに、次のような key のキャストが発生します。10 進数の int として妥当な形式の String は、 数値の前に + 記号がついていない限り、 int 型にキャストされます。 つまり、キーに “8” を指定すると、実際には 8 として格納されるということです。
PHPマニュアル:配列
『Undefined offset』にまつわるエラーの話
Notice: Undefined offset
ですが、PHP 8以降だと、Warning:Undefined array key
となり、エラーレベル・エラー文が変更されています。
このように、PHPのバージョンによっては挙動が異なることがあります。また、未定義の配列要素の参照元について、型が異なればエラーも異なってきます。その違いを知るため、「PHPバージョンの差によるエラーの違い」と「参照元の型の差によるエラーの違い」を確認してみました。
挙動の確認には、「PHP Sandbox」というPHPテストサイトを使用しました。
こちらのサイトではPHPのバージョンを指定して、コードの実行・結果確認ができます!バージョンを同時実行することも可能なので、実行結果を比較したい!という場合も便利です✨
array型:未定義の配列インデックスを参照した場合
$test_array = array("test0", "test1"); // array型
var_dump($test_array[2]);
実行結果
// PHP 7.2.0, PHP 7.4.0
Notice: Undefined offset: 2
NULL
// PHP 8.0.0
Warning: Undefined array key 2
NULL
PHP 8 では、Warning: Undefined array key
と、エラーレベル・エラー文言が変更になっています。エラーレベルが通知(Notice)から警告(Warning)に上がっており、いずれ警告からエラーに段階が上がることも考えられるため、Undefined offset
もしくはUndefined array key
が発生している箇所は、早めに解消していた方が良さそうです…!
array型以外:未定義の配列インデックスを参照した場合
$test_null = NULL; // NULL型
var_dump($test_null[2]);
実行結果
// PHP 7.2.0
NULL
// PHP 7.4.0
Notice: Trying to access array offset on value of type null
NULL
// PHP 8.0.0
Warning: Trying to access array offset on value of type null
NULL
PHP 7.4.0 より前のバージョンでは、array 型以外の変数に対して、未定義の配列要素を参照してもエラーは発生しませんでした。しかし、PHP 7.4.0 以降は、「array 型以外の値に、配列参照しようとしてるけど…」といったメッセージが返却されるため、参照元の型には注意が必要そうです。
例ではNULL 型で記述していますが、int 型・bool 型の変数を対象に実行した場合も、同様のエラーが発生します(その際は、上記エラー文言のtype部分が、それぞれ int
と bool
になります)
string型:未定義の配列インデックスを参照した場合
$test_string = 'string'; // string型
var_dump($test_string[2]);
実行結果
// PHP 7.2.0, PHP 7.4.0, PHP 8.0.0
string(1) "r"
string型の変数に対して、配列のインデックスを参照するように記述すると、文字列内の任意の文字にアクセスすることができます。
$str[42] のように、 角括弧を使用してゼロから始まるオフセットを指定すると、 文字列内の任意の文字にアクセスし、修正することが可能です。 つまり、文字列を文字の配列として考えるわけです。
PHPマニュアル:文字列
ちなみに、範囲外のインデックスを指定すると、PHP7 ではNotice: Uninitialized string offset
のエラーが発生します(PHP8 だとWarning になります)
まとめ
今回は、Undefinend offset
をはじめとした、未定義の配列エラーについて紹介しました。
エラーの回避方法については割愛させていただきましたが、isset関数やarray_key_exists関数の使用が良いみたいです✨(どちらも配列の要素やキーの存在チェックが効果的みたいですね)
「未定義の値参照を回避するためにも、配列の要素を雑に指定しないこと」は勿論!実行するPHPのバージョンによってはエラーが発生しない、などの差もあるため、「しっかりと実行環境の意識をすること」も大事だなと改めて感じました。
株式会社ウイングドアは福岡のシステム開発会社です。
現在、私達と一緒に"楽しく仕事が出来る仲間"として、新卒・中途採用を絶賛募集しています!
ウイングドアの仲間達となら楽しく仕事できるかも?と興味をもった方、
お気軽にお問い合わせ下さい!