Code Fix

中級

array_merge()は文字列キーが同じだと上書きし、数値キーは振り直す

array_merge()は文字列キーが重複していると後の配列の値で上書きし、数値キーは重複を無視して0から振り直します。片方の配列のデータが消えたように見えるのは、この仕様が原因です。

なぜエラーが出ないのか

出力: ,
(エラーなし)
PHPは何も報告しません。文法として正しいためです
出力: ,
実際の挙動 — 期待した結果と食い違っている箇所
見つけ方
エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます

このエラーが出る典型パターン

パターン1

 1  <?php
 2  $defaults = ["theme" => "light", "size" => "M"];
 3  $custom = ["theme" => "dark"];
 4  $merged = array_diff     ($defaults, $custom);
                     ^
 5  echo $merged["theme"] . "," . $merged["size"];
出力: ,期待: dark,M (エラーにはなりません)

array_diffは差分を取る関数で、意図したマージにはなりません。同じ文字列キーを持つ配列を後勝ちで統合したい場合はarray_mergeを使います。

直し方: array_diffarray_merge にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  <?php
 2  $a = ["x" => 1, "y" => 2];
 3  $b = ["y" => 99, "z" => 4];
                  ^
 4  $merged = array_merge($a, $b);
 5  echo $merged["x"] . "," . $merged["y"] . "," . $merged["z"];
出力: 1,99,4期待: 1,3,4 (エラーにはなりません)

array_mergeは文字列キー"y"が両方の配列にある場合、後の配列($b)の値で上書きします。意図した値を後の配列に渡す必要があります。

直し方: 993 にします。

この問題を解いてみる →

パターン3

 1  <?php
 2  $base = [10, 20];
 3  $extra = [30, 40];
 4  $merged = array_merge($base, $extra);
 5  echo count($merged) . ":" . $merged[0]           ;
                                          ^
出力: 4:10期待: 4:10,20,30,40 (エラーにはなりません)

数値キーの配列同士をarray_mergeすると、キーは0から振り直されて連結されます(この点は文字列キーと違い上書きされません)。全要素を確認するにはimplodeで並べて出力する必要があります。

直し方: $merged[0]implode(",", $merged) にします。

この問題を解いてみる →

よくある誤解

「array_mergeは両方の配列のすべての要素を残してくれるはず」という思い込みは誤りです。文字列キーが衝突すれば後勝ちで上書きされ、データが失われます。キーを保持したい場合は+演算子を使う必要があります。

まとめ

array_merge()は文字列キーが同じだと上書きし、数値キーは振り直すは中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)