PHP|Notice: Array to string conversion 警告の対処方法(複数)

PHPで配列を扱う際に以下のような警告が発生してしまうことがあります。

$a = array(1, 2, array(3));
echo $a; // Notice: Array to string conversion in a.php on line 2
$b = $a . "s";      // Notice: Array to string conversion in a.php on line 3
$b = "$a[2]";       // Notice: Array to string conversion in a.php on line 4
$b = "$a[2][0]";    // Notice: Array to string conversion in a.php on line 5
$b = implode($a);   // Notice: Array to string conversion in a.php on line 6
$b = "$this->a[0]"; // Notice: Array to string conversion in a.php on line 7

Notice: Array to string conversion自体は「配列が文字列に変換」されてしまうという趣旨の警告メッセージです。

配列は、文字列化されると強制的にArrayという文字列に変換されてしまうため、このような警告が発生します。また式の記述方法が間違っている場合にも、このような警告が発生してしまうことがあります。

この手の文字列変換はプログラムの厳格さの観点では問題があるため、必要に応じて対処が必要となります。原因別に異なる対処が必要となるため、以下を参考に対処してください。

原因と対処

echo/print文による出力時に警告が発生するケース

echo文やprint文は、変数の値を一度文字列化した上で出力するため、配列型の値をそのまま与えてしまうと今回のようなエラーの発生に繋がってしまいます。

配列型の要素を含んだ配列やオブジェクトを出力する際には、print_r関数やvar_dump関数を用いる必要があります。

$a = array(9, "a");
echo $a;      // "Array"という文字列が表示される
print_r($a);  // "Array([0] => 9, [1] => a)"という詳細な情報が表示される
var_dump($a); // array(2) {[0] => int(9), [1] => string(1) "a"}

標準関数呼び出し時に警告が発生するケース

配列型の値を受け取るPHP標準関数を用いた際に、今回のような警告が発生する場合があります。関数内部で配列型の要素が文字列変換されてしまっていることが原因です。

$a = array(1, 2, array(3, 4)); // 配列型の要素を含んだ配列
$b = implode($a); // Notice: Array to string conversion in a.php on line 2
echo $b; // "12Array"(implode関数内部で`array(3, 4)`が文字列変換された)

不定な配列が生まれてしまった原因を各自で探る必要があります。場合によっては、array_filter関数で配列型の要素を排除することもできます。

$a = array(1, 2, array(3, 4));
$b = array_filter($a, function ($e) { return !is_array($e); });
echo implode($b); // "12"

ダブルクォーテーション文字列の変数展開で警告が発生するケース

ダブルクォーテーション内の変数が文字列展開される際にも同様の問題が発生します。この場合は複数のエラーケースが存在します。

展開後の値が配列だった場合

添字アクセス時のアクセス先の要素が配列型だった場合に警告が発生します。

$a = array(array(6), 4);
$b = "{$a[0]}"; // Notice: Array to string conversion in a.php on line 2
$b = "{$a[1]}"; // "4"

多次元配列へのアクセスを行った場合

ダブルクォーテーション内で多次元配列への添字アクセスを行った場合には、一次元目の添字アクセスのみが評価されます。この場合の一次元目の要素は配列型であるため、警告が発生することになります。

$a = array(array(1, 2));
echo $a[0][1];     // "2"(一般的な式では問題ない)
echo "$a[0][1]";   // "Array[1]" Notice: Array to string conversion in a.php on line 3
echo "{$a[0][1]}"; // "2"(波括弧で囲って対処)

多次元配列へのアクセスを完全に行うためには、展開対象の式を波括弧({})で囲う必要があります(例:"{$a[0][1]}")。

メンバ変数へのアクセスを行った場合

クラス・オブジェクトの配列型メンバ変数を参照する際にも同等の問題が発生する場合があります。この場合はメンバへのアクセス($obj->a)のみが展開され[1]による添字アクセスが評価されません。ダブルクォーテーション内で配列型のメンバ変数を厳格に添字アクセスさせたい場合には、展開対象の式を波括弧({})で囲う必要があります(例:"{$obj->a[1]}")。

class T { public $a = array(1, 2); }
$obj = new T;
echo $obj->a[1];     // "2"(一般的な式では問題ない)
echo "$obj->a[1]";   // "Array[1]" Notice: Array to string conversion in a.php on line 4
echo "{$obj->a[1]}"; // "2"(波括弧で囲って対処)

Array[0] や Array['key'] という出力結果について

ちなみに巷でよく問題になる、"$this->array[0]"Array[0]として出力されてしまう問題の原因は、配列型メンバ変数$this->arrayが文字列変換によってArray文字列に変換され、残りの[0]が添字アクセスではなく一般的な文字列として評価されてしまっていることが原因となっています。

この問題に対処するためには、対象の式を波括弧で囲う必要があります("{$this->array[0]}")。これによって式の評価範囲が明確化され、正確な値展開が行われるようになります。

広告