PHPの開発中に「Uncaught Error: Cannot use a scalar value as an array」というエラーに直面することがあります。このエラー自体はPHP7以前から存在しますが、PHP8.0からはnullに対する[]追加操作が警告(Notice)からエラー(Fatal Error)に格上げされたため、バージョンアップ時に突然発生するケースが増えています。
エラーが起きる原因
このエラーは、すでにスカラー値が代入されている変数に対して、配列のように要素を追加しようとしたときに発生します。
スカラー値とは? 単一の値を表すデータの型のこと。PHPでは「整数(int)」「浮動小数点数(float)」「文字列(string)」「論理値(bool)」を指します。
エラーになるコードの例
$data = 10;
$data[] = "新しく追加したい要素";
この場合、変数$dataは配列ではないため[]を使った追加操作(Auto-vivificationの失敗)を受け付けません。
基本的な解決策:変数の初期化
最も単純かつ確実な解決策は、配列として使う前に**空の配列で変数を初期化(リセット)**することです。
$data = 10;
// 配列として使いたいタイミングで再定義
$data = [];
$data[] = "要素1";
$data[] = "要素2";
var_dump($data);
このように$data = [];と明示的に宣言し直すことで、以前のデータが破棄され、安全に配列として扱えるようになります。
実務でよくある発生パターンと対策
実際の開発では、明示的に数値を代入していなくてもこのエラーに遭遇することがあります。
外部データの取得失敗
APIやデータベースから値を取得した際、正常なら配列が返ってくるはずが、エラーでfalseやエラーコード(数値)が返ってきた場合に発生します。
対策:型を確認してから操作する
if (!is_array($data)) {
$data = [];
}
$data[] = "追加データ";
ループ内での変数名の重複
同じ変数名を使い回していると、意図せず前の処理で入れたスカラー値が残っていることがあります。
対策:ループの直前で初期化を徹底する
$items = [1, 2, 3];
$result = "成功";
$result = [];
foreach ($items as $item) {
$result[] = $item * 2;
}
セッションやフォームの値をそのまま配列として使った場合
フォームから送信された値やセッションの値は文字列として渡されます。 それをそのまま配列として扱おうとするとエラーになります。
$ids = $_POST['ids'];
$ids[] = 2;
対策:受け取り時に型を確認・変換する
$ids = $_POST['ids'] ?? [];
if (!is_array($ids)) {
$ids = [$ids];
}
$ids[] = 2;
JSONデコード失敗時にfalseが返る場合
json_decode()は不正なJSON文字列を受け取るとnullを返します。 これを配列として扱おうとするとエラーになります。
$json = "不正なJSON文字列";
$data = json_decode($json, true);
$data[] = "追加データ";
対策:json_decode後に必ず検証する
$json = "不正なJSON文字列";
$data = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE || !is_array($data)) {
$data = [];
}
$data[] = "追加データ";
PHPバージョンによる挙動の違い
以前のPHP(7.4以前)では、変数がnullの場合に[]で値を追加すると自動的に配列として扱われましたが、PHP8.0以降では型チェックが厳格化されています。 以前動いていたコードが、サーバーのバージョンを上げたら動かなくなったという場合は、この厳格化が原因である可能性が高いです。常に「配列を使う前は初期化する」という癖をつけておきましょう。
この記事のまとめ
「Cannot use a scalar value as an array」を防ぐには、**「配列を使う直前で必ず初期化する」**という習慣が重要です。
モダンなPHP開発においては、最初から$data = []と定義するか、関数の戻り値に型宣言を活用して、予期せぬスカラー値が混入しない設計を心がけましょう。
型宣言で混入を防ぐ
関数の引数や戻り値に型宣言を使うことで、意図しないスカラー値の混入を設計レベルで防げます。
function getItems(): array
{
return [];
}
$data = getItems();
$data[] = "要素1";
PHP8.0以降ではstrict_types=1を宣言することでさらに厳格な型チェックが適用されます。
<?php
declare(strict_types=1);
ファイルの先頭に記述することで、型が一致しない場合に自動変換されず即座にエラーが発生するようになります。これにより意図しない型の混入を早期に発見でき、バグの防止につながります。