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);

ファイルの先頭に記述することで、型が一致しない場合に自動変換されず即座にエラーが発生するようになります。これにより意図しない型の混入を早期に発見でき、バグの防止につながります。



関連記事