2009-09-07 19 views
19

Czytam dane JSON z PHP i dane zawierają puste obiekty (np. {}). Problem polega na tym, że mam do czynienia z przypadkiem, gdy obiekt jest pusty w inny sposób, ale nie mogę znaleźć wystarczająco dobrego sposobu na sprawdzenie. empty(get_object_vars(object)) wygląda zbyt przerażająco i bardzo nieefektywnie. Czy istnieje dobry sposób na sprawdzenie?Jak sprawdzić, czy obiekt JSON jest pusty w PHP?

+0

pokrewne: https://stetylverflow.com/q/9412126/3995261 – YakovL

Odpowiedz

22

Ile obiektów Chyba że empty(get_object_vars($object)) lub odlewanie do tablicy okaże się poważnym spowolnieniem/wąskim gardłem, nie martwię się o to - rozwiązanie Grega jest po prostu w porządku

Sugeruję użyciu flagi $associative podczas dekodowania danych JSON, ale:

json_decode($data, true) 

Ten dekoduje obiekty JSON jako zwykły starych tablic PHP zamiast jak stdClass obiektów. Następnie możesz sprawdzić puste obiekty używając empty() i tworzyć obiekty klasy zdefiniowanej przez użytkownika, zamiast używać stdClass, co jest prawdopodobnie dobrym pomysłem na dłuższą metę.

24

Można rzucić go do tablicy (niestety nie można tego zrobić w terminie wezwania do empty():

$x = (array)$obj; 
if (empty($x)) 
    ... 

lub odlewane do tablicy i count():

if (count((array)$obj)) 
    ... 
+0

Czy to nie to samo co z get_object_vars? To znaczy. nie jest naprawdę skuteczny? :) – vava

+2

Nie testowałem tego, ale jeśli nie masz problemów z wydajnością i uznałeś to za wąskie gardło, nie sądzę, że warto się nim martwić. – Greg

+1

Nie jest łatwo przestać martwić się niepotrzebnymi przekształceniami macierzy, jeśli przez większość życia byłeś programistą C++ :) Oznacza to przydzielanie pamięci i kopiowanie rzeczy na coś, co powinno zająć tylko szybkie sprawdzenie, czy bit jest ustawiony. – vava

0

Musiałem powiedzieć, czy obiekt był pusty, czy nie, ale musiałem również zignorować prywatne i chronione właściwości, więc zrobiłem tę małą funkcję, dzięki której można to zrobić.

function empty_obj(&$object, $ignore_private = true, $ignore_protected = true) { 
    $obj_name = get_class($object); 
    $obj = (array)$object; 

    foreach(array_keys($obj) as $prop) { 
    $is_private = $is_protected = false; 

    $prop = preg_replace("/[^\w*]/", '', $prop); 
    $prop_name = str_replace(array($obj_name, '*'), '', $prop); 

    if(preg_match("~^$obj_name$prop_name$~", $prop)) 
     $is_private = true; 
    if(preg_match("~^\*$prop_name$~", $prop)) 
     $is_protected = true; 

    if(!$is_private || !$is_protected || ($is_private && !$ignore_private) || ($is_protected && !$ignore_protected)) 
     return; 
    } 
    return true; 
} 
0

Nie jestem pewien, czy jest to bardziej lub mniej skuteczne niż odlewania do tablicy, ale przypuszczam więcej. Możesz po prostu zacząć pętlę obiektu i jak tylko znajdziesz coś, na co masz odpowiedź, i przestań zapętlać.

function is_obj_empty($obj){ 
    if(is_null($obj)){ 
     return true; 
    } 
    foreach($obj as $key => $val){ 
     return false; 
    } 
    return true; 
} 
3

Spróbuj bez użycia empty() który jest:

get_object_vars($obj) ? TRUE : FALSE; 

Na PHP docs możemy przeczytać UWAGA:

Podczas korzystania empty() na niedostępnych właściwości obiektu, __isset() przeciążenia metoda zostanie wywołana , jeśli zostało zadeklarowane.

Czyli podczas korzystania empty() na obiekcie, który jest o __get() metodę, to zawsze zwraca True.

Powiązane problemy