Pytanie PHP json_encode jako obiekt po tablicy PHP unset ()


Mam dziwne zachowanie z json_encode po usunięciu klucza tablicy numerycznej za pomocą unset. Poniższy kod powinien wyjaśnić problem. Uruchomiłem go zarówno z CLI, jak i jako mod Apache:

Informacje o wersji 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

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

Wyjście programu

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

Jak widać, za pierwszym razem $a jest konwertowany na JSON, jest zakodowany jako tablica javascript. Za drugim razem (po unset połączenie) $a jest zakodowany jako obiekt javascript. Dlaczego tak jest i jak mogę temu zapobiec?


18
2017-10-06 02:28


pochodzenie


+1, ponieważ dobrze jest zobaczyć dobrze zadane pytanie. :) - Spudley


Odpowiedzi:


Powodem tego jest to, że twoja macierz ma w sobie dziurę: ma indeksy 0 i 2, ale pomija 1. JSON nie może kodować tablic z dziurami, ponieważ składnia macierzy nie obsługuje indeksów.

Możesz kodować array_values($a) zamiast tego, która zwróci tablicę ponownie indeksowaną.


17
2017-10-06 02:33



Alternatywnie możesz posortować tablicę po rozbrojeniu elementu. - NullUserException
@NullUserException Chociaż będzie to miało efekt uboczny, dobrze, sortowanie tablicy. - zneak
Dla tych, którzy zastanawiają się nad unset zachowanie, zobacz poniższy link i przewiń w dół do "Przydatnych funkcji": us3.php.net/manual/en/language.types.array.php  "Funkcja unset () pozwala na usuwanie kluczy z tablicy. Należy pamiętać, że tablica nie zostanie ponownie zindeksowana" - leepowers
@NullUserException Świetny dodatek! Potrzebne do uporządkowania tablicy - zabicie dwóch ptaków jednym kamieniem. - sjkm


Dodatkowo array_values technika jest możliwa do zastosowania array_splice i usuń element i ponownie zindeksuj w jednym kroku:

unset($a[1]);

Zamiast:

array_splice($a, 1, 1);

5
2017-10-06 02:55



absolutnie doskonały sposób na wykonanie pracy bez zbędnego powiększania kolekcji, dzięki! - CookieMonster
To. Najbardziej elegancki sposób. - DQM


Spróbuj użyć opcji JSON_FORCE_OBJECT dla json_encode, na przykład: json_encode($a, JSON_FORCE_OBJECT) więc zawsze będziesz mieć ten sam rezultat.


2
2017-10-08 11:18