Używam json_decode()
czegoś takiego:
$myVar = json_decode($data)
Co daje mi następujący wynik:
[highlighting] => stdClass Object
(
[448364] => stdClass Object
(
[Data] => Array
(
[0] => Tax amount liability is .......
Chcę uzyskać dostęp do wartości ciągu w kluczu [0]. Kiedy próbuję zrobić coś takiego:
print $myVar->highlighting->448364->Data->0;
Otrzymuję ten błąd:
Błąd analizy: błąd składni, nieoczekiwany T_DNUMBER
Wydaje się, że problem dotyczy dwóch liczb / liczb całkowitych.
php
object
properties
avinash shah
źródło
źródło
Odpowiedzi:
Zaktualizowano dla PHP 7.2
PHP 7.2 wprowadziło zmianę behawioralną dotyczącą konwersji kluczy numerycznych w rzutowaniu obiektów i tablic , co naprawia tę konkretną niespójność i sprawia, że wszystkie poniższe przykłady zachowują się zgodnie z oczekiwaniami.
Jedna rzecz mniej, o którą należy się mylić!
Oryginalna odpowiedź (dotyczy wersji wcześniejszych niż 7.2.0)
PHP ma swój udział w ciemnych zaułkach, w których naprawdę nie chcesz się znaleźć. Właściwości obiektów o nazwach będących liczbami są jedną z nich ...
Czego ci nigdy nie powiedzieli
Fakt nr 1: Nie można łatwo uzyskać dostępu do właściwości o nazwach, które nie są prawidłowymi nazwami zmiennych
$a = array('123' => '123', '123foo' => '123foo'); $o = (object)$a; echo $o->123foo; // error
Fakt # 2: Możesz uzyskać dostęp do takich właściwości za pomocą składni nawiasów klamrowych
$a = array('123' => '123', '123foo' => '123foo'); $o = (object)$a; echo $o->{'123foo'}; // OK!
Fakt # 3: Ale nie, jeśli nazwa właściwości składa się z samych cyfr!
$a = array('123' => '123', '123foo' => '123foo'); $o = (object)$a; echo $o->{'123foo'}; // OK! echo $o->{'123'}; // error!
Przykład na żywo .
Fakt # 4: No chyba, że obiekt nie pochodzi z tablicy.
$a = array('123' => '123'); $o1 = (object)$a; $o2 = new stdClass; $o2->{'123'} = '123'; // setting property is OK echo $o1->{'123'}; // error! echo $o2->{'123'}; // works... WTF?
Przykład na żywo .
Całkiem intuicyjny, nie zgadzasz się?
Co możesz zrobić
Opcja nr 1: zrób to ręcznie
Najbardziej praktycznym podejściem jest po prostu rzutowanie interesującego Cię obiektu z powrotem do tablicy, która pozwoli ci uzyskać dostęp do właściwości:
$a = array('123' => '123', '123foo' => '123foo'); $o = (object)$a; $a = (array)$o; echo $o->{'123'}; // error! echo $a['123']; // OK!
Niestety nie działa to rekurencyjnie. Więc w twoim przypadku musisz zrobić coś takiego:
$highlighting = (array)$myVar->highlighting; $data = (array)$highlighting['448364']->Data; $value = $data['0']; // at last!
Opcja nr 2: opcja jądrowa
Alternatywnym podejściem byłoby napisanie funkcji, która rekurencyjnie konwertuje obiekty na tablice:
function recursive_cast_to_array($o) { $a = (array)$o; foreach ($a as &$value) { if (is_object($value)) { $value = recursive_cast_to_array($value); } } return $a; } $arr = recursive_cast_to_array($myVar); $value = $arr['highlighting']['448364']['Data']['0'];
Nie jestem jednak przekonany, że jest to lepsza opcja pod każdym względem, ponieważ niepotrzebnie rzutuje na tablice wszystkie właściwości, którymi nie jesteś zainteresowany, a także te, którymi jesteś.
Opcja nr 3: grając mądrze
Alternatywą dla poprzedniej opcji jest użycie wbudowanych funkcji JSON:
$arr = json_decode(json_encode($myVar), true); $value = $arr['highlighting']['448364']['Data']['0'];
Funkcje JSON z łatwością wykonują rekursywną konwersję na tablicę bez konieczności definiowania jakichkolwiek funkcji zewnętrznych. Jakkolwiek wygląda to pożądane, ma tę wadę "nuke", jak opcja # 2, a dodatkowo wadę polegającą na tym, że jeśli wewnątrz obiektu znajdują się jakieś łańcuchy, muszą one być zakodowane w UTF-8 (jest to wymagane
json_encode
).źródło
->date
lub->timezone
,null
zostanie zwrócony tylko . Zauważyłem, że jeśli var_dumped obiekt przed użyciem tych właściwości, zwracane są właściwe wartości. Klonowanie tego nie naprawia, więc myślę, że to naprawdę ma coś wspólnego z dostępem, któryvar_dump
robi ... Potem zobaczyłem twoją Opcję # 1 i voilá, dostęp do niej jako tablica ($objCastAsArray['date']
) działał jak urok.$o = unserialize('O:8:"StdClass"' . substr(serialize($a),1));
Chciałem tylko dodać do wymownego wyjaśnienia Jona powód, dla którego to się nie udaje. Dzieje się tak dlatego, że podczas tworzenia tablicy php konwertuje klucze na liczby całkowite - jeśli to możliwe - co powoduje problemy z wyszukiwaniem tablic, które zostały rzutowane na obiekty, po prostu dlatego, że klucz numeryczny jest zachowany. Jest to problematyczne, ponieważ wszystkie opcje dostępu do właściwości oczekują lub są konwertowane na łańcuchy. Możesz to potwierdzić, wykonując następujące czynności:
$arr = array('123' => 'abc'); $obj = (object) $arr; $obj->{'123'} = 'abc'; print_r( $obj );
Który dałoby:
stdClass Object ( [123] => 'abc', [123] => 'abc' )
Tak więc obiekt ma dwa klucze właściwości, jeden numeryczny (do którego nie można uzyskać dostępu) i jeden oparty na łańcuchu. To jest powód, dla którego Jon's
#Fact 4
działa, ponieważ ustawienie właściwości za pomocą nawiasów klamrowych oznacza, że zawsze definiujesz klucz oparty na ciągach, a nie numeryczny.Biorąc rozwiązanie Jona, ale obracając je na głowie, możesz wygenerować obiekt ze swojej tablicy, który zawsze ma klucze oparte na ciągach, wykonując następujące czynności:
Od teraz możesz użyć jednego z poniższych, ponieważ dostęp w ten sposób zawsze konwertuje wartość wewnątrz nawiasu klamrowego na ciąg:
$obj->{123}; $obj->{'123'};
Dobry stary nielogiczny PHP ...
źródło
Jeśli obiekt zaczyna się od
@
:SimpleXMLElement Object ( [@attributes] => Array ( [href] => qwertyuiop.html [id] => html21 [media-type] => application/xhtml+xml ) )
Musisz użyć:
bo
$parent_object->{'@attributes'}
albo$parent_object['@attributes']
nie będzie działać.źródło
Skopiowałem tę funkcję z sieci. Jeśli działa tak, jak wskazuje („Funkcja konwertująca obiekty stdClass na tablice wielowymiarowe”), wypróbuj następujące rozwiązania:
<?php function objectToArray($d) { if (is_object($d)) { // Gets the properties of the given object // with get_object_vars function $d = get_object_vars($d); } if (is_array($d)) { /* * Return array converted to object * Using __FUNCTION__ (Magic constant) * for recursive call */ return array_map(__FUNCTION__, $d); } else { // Return array return $d; } } ?>
objectToArray
funkcji[highlighting][448364][Data][0]
Źródło: PHP stdClass na Array i Array na stdClass
źródło
Ostatnia alternatywa dla wyczerpującej odpowiedzi Jona:
Po prostu użyj json_decode () z drugim parametrem ustawionym na true .
$array = json_decode($url, true);
To następnie zwraca tablicę asocjacyjną zamiast obiektu, więc nie ma potrzeby konwersji po fakcie.
Może to nie być odpowiednie dla każdej aplikacji, ale naprawdę pomogło mi w łatwym odwołaniu się do właściwości obiektu źródłowego.
Rozwiązanie zostało znalezione w tym samouczku - http://nitschinger.at/Handling-JSON-like-a-boss-in-PHP/
pozdrowienia
źródło
Dostęp do właściwości obiektu, których nazwa jest liczbą. Najczęściej potrzebne po rzutowaniu tablicy na obiekt.
$arr = [2,3,7]; $o = (object) $arr; $t = "1"; $t2 = 1; $t3 = (1); echo $o->{1}; // 3 echo $o->{'1'}; // 3 echo $o->$t; // 3 echo $o->$t2; // 3 echo $o->$t3; // 3 echo $o->1; // error echo $o->(1); // error
źródło
Obawiam się, że nie możesz nazywać obiektów zaczynających się od liczb. Zmień nazwę pierwszego z nich na „448364”, zaczynając od litery.
Drugi to tablica, do której dostęp należy uzyskać za pomocą nawiasów kwadratowych:
print myVar->highlighting->test_448364->Data[0]
zamiast
źródło