PHP json_encode как объект после того, как массив PHP unset ()

Я столкнулся с нечетным поведением с json_encode после удаления числового ключа массива с unset . Следующий код должен сделать проблему понятной. Я запустил его как из CLI, так и в стиле Apache:

Информация о версии PHP:

 C:\Users\usr\Desktop>php -v PHP 5.3.1 (cli) (built: Nov 20 2009 17:26:32) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies 

PHP-код

 <?php $a = array( new stdclass, new stdclass, new stdclass ); $a[0]->abc = '123'; $a[1]->jkl = '234'; $a[2]->nmo = '567'; printf("%s\n", json_encode($a)); unset($a[1]); printf("%s\n", json_encode($a)); с <?php $a = array( new stdclass, new stdclass, new stdclass ); $a[0]->abc = '123'; $a[1]->jkl = '234'; $a[2]->nmo = '567'; printf("%s\n", json_encode($a)); unset($a[1]); printf("%s\n", json_encode($a)); 

Выход программы

 C:\Users\usr\Desktop>php test.php [{"abc":"123"},{"jkl":"234"},{"nmo":"567"}] {"0":{"abc":"123"},"2":{"nmo":"567"}} 

Как вы можете видеть, первый раз, когда $a преобразуется в JSON, он кодируется как массив javascript. Во второй раз (после вызова unset ) $a закодирован как объект javascript. Почему это и как я могу предотвратить это?

Причина этого в том, что в вашем массиве есть дыра: он имеет индексы 0 и 2, но пропускает 1. JSON не может кодировать массивы с отверстиями, потому что синтаксис массива не поддерживает индексы.

Вы можете закодировать array_values($a) вместо этого, который вернет повторно проиндексированный массив.

В дополнение к array_values можно использовать array_splice и удалить элемент и повторно проиндексировать за один шаг:

 unset($a[1]); 

Вместо:

 array_splice($a, 1, 1); 

Попробуйте использовать параметр JSON_FORCE_OBJECT для json_encode, например: json_encode($a, JSON_FORCE_OBJECT) чтобы вы всегда имели одинаковый результат.