#Когда возникает ошибка
В PHP выражение $data["user"] работает с массивами, а json_decode($json) по умолчанию возвращает для JSON-объекта экземпляр stdClass. Обращение к нему как к массиву вызывает Cannot use object of type stdClass as array. При этом массив JSON вида [1,2] остаётся массивом PHP: важно проверить реальный корень структуры.
#Причины и признаки
| Возможная причина | Как узнать | Что делать |
|---|---|---|
json_decode без associativeПараметр associative не передан, объекты JSON становятся stdClass. | var_dump(get_debug_type($data)) показывает stdClass. | Передавайте true при декодировании, если дальнейший код ожидает массив. |
Смешаны обращения к массиву и объектуВ одном коде используются и ->name, и ["name"] для одних данных. | Одна строка работает, другая падает на той же переменной. | Выберите один стиль обращения для всех вложенных JSON-объектов. |
| JSON декодирован неудачноСтрока содержит синтаксическую ошибку или неожиданный формат. | json_decode возвращает null либо бросает JsonException с флагом. | Сначала проверьте JSON, затем свойства или ключи. |
#Пошаговая диагностика и устранение
- Установите, на каком объекте возникает исключениеОткройте файл из сообщения об ошибке в редакторе, перейдите к указанной строке и найдите переменную слева от
[...]. В закрытой тестовой среде запишитеget_debug_type($data)и, при необходимости, безопасные названия ключей. Не выводите весь JSON клиента на общедоступную страницу и не публикуйте токены API. - Найдите место вызова json_decodeВ редакторе используйте поиск по проекту Ctrl+Shift+F →
json_decode(. Проверьте аргументы конкретного вызова и откуда поступает строка: файл, HTTP-ответ или база. Если в этой точке уже переданоtrue, причиной может быть другой объект, который отдельно добавлен в массив; отследите его создание. - Выберите формат для дальнейшего кодаЕсли проект обращается через квадратные скобки, используйте
json_decode($json, true, 512, JSON_THROW_ON_ERROR)и затем проверяйтеis_array($data). Если проект преимущественно использует объекты, оставьте стандартную форму и исправьте доступ на$data->user, предварительно проверяяisset($data->user). Не смешивайте стили в глубоко вложенных полях. - Обрабатывайте несуществующие и пустые поля отдельноПри массивном варианте используйте
$data["user"]["name"] ?? nullлишь если отсутствие значения разрешено. Если поле обязательно, проверьтеissetилиarray_key_existsв зависимости от допустимости null и покажите контролируемую ошибку схемы данных. Удалённый API может вернуть массив вместо ожидаемого объекта или наоборот. - Добавьте проверку некорректного JSONОборачивайте декодирование с
JSON_THROW_ON_ERRORвtry/catch (JsonException $e). Запишите в закрытый журнал краткий текст ошибки без сырого содержимого запроса. При неверной UTF-8 на входе сначала разберитесь с источником кодировки, а не подменяйте его ошибочный ответ пустым массивом. - Проверяйте исправление на разных формах JSONСохраните правку в тестовом файле; выполните
php -l файл.php, затем запустите тест на обычном объекте, отсутствующем поле и массиве верхнего уровня. Ожидаемый тип после декодирования сtrue— array, а вызов с объектом не использует квадратные скобки. Если проблема остаётся, найдите вторую точкуjson_decodeили переопределение переменной. - Откатите изменение, если нарушился контрактЕсли сторонний модуль ожидает
stdClass, не меняйте глобально формат декодирования в общей функции: верните исходную версию из резервной копии и преобразуйте только данные конкретного обработчика. Проверьте сериализацию обратно в JSON, поскольку ассоциативные массивы и объекты могут кодироваться по-разному.
#Проверяемый пример и команды
$data->user->name с проверками; выбирать нужно один способ.<?php
$json = '{"user":{"name":"Анна"}}';
try {
$data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
if (!is_array($data) || !isset($data['user']['name'])) {
throw new UnexpectedValueException('Нет обязательного имени');
}
echo $data['user']['name'] . PHP_EOL;
} catch (JsonException $e) {
echo 'Некорректный JSON' . PHP_EOL;
}#Проверка исправления и действия при неудаче
После исправления конкретный запрос обрабатывается без Cannot use object ... as array, неверный JSON даёт контролируемую ошибку, а вложенные значения извлекаются ожидаемым способом. При повторении ошибки запишите точный тип вложенного элемента и его путь в структуре без раскрытия пользовательских данных.