2009-09-07 53 views
19

Estoy leyendo datos JSON con PHP y esos datos contienen objetos vacíos (como {}). Entonces, el problema es que tengo que manejar el caso cuando el objeto está vacío de manera diferente, pero no puedo encontrar una forma lo suficientemente buena para hacer el control. empty(get_object_vars(object)) parece demasiado aterrador y muy ineficiente. ¿Hay una buena manera de hacer el cheque?¿Cómo comprobar si el objeto JSON está vacío en PHP?

+0

relacionado: https://stackoverflow.com/q/9412126/3995261 – YakovL

Respuesta

22

¿Cuántos objetos ¿a menos que empty(get_object_vars($object)) o fundición en matriz demuestre ser una gran desaceleración/cuello de botella, no me preocuparía - la solución de Greg está bien.

me gustaría sugerir el uso de la bandera de la $associative cuando se decodifica los datos JSON, sin embargo:

json_decode($data, true) 

Este decodifica objetos JSON como viejas matrices PHP planos en lugar de como stdClass objetos. Luego puede verificar si hay objetos vacíos usando empty() y crear objetos de una clase definida por el usuario en lugar de usar stdClass, lo cual es probablemente una buena idea a largo plazo.

24

Se podía echarlo a una matriz (por desgracia no se puede hacer esto dentro de una llamada a empty():

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

o yeso para una matriz y count():

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

¿No es lo mismo que con get_object_vars? Es decir. no es realmente eficiente? :) – vava

+2

No lo he probado, pero a menos que tenga problemas de rendimiento y haya identificado esto como un cuello de botella, no creo que valga la pena preocuparse por ello. – Greg

+1

No es fácil dejar de preocuparte por las transformaciones de matriz innecesarias si fueras un programador de C++ la mayor parte de tu vida :) Significa asignación de memoria y copiado de algo que debería llevar solo una comprobación rápida si se establece un bit. – vava

0

Tenía que decir si un objeto estaba vacío o no, pero también tuve que ignorar las propiedades privadas y protegidas, así que hice esta pequeña función con la que puede hacer esto.

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

No estoy seguro de si esto es más o menos efectivo que el lanzamiento a una matriz, pero supongo que más. Podrías comenzar a recorrer el objeto y tan pronto como encuentres algo, tendrás una respuesta y dejarás de repetir.

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

Try sin utilizar empty() cuales es:

get_object_vars($obj) ? TRUE : FALSE; 

En PHP docs podemos leer la nota:

Al utilizar empty() en propiedades de los objetos de difícil acceso, se llamará la sobrecarga de métodos __isset() , si está declarado.

Lo que significa que cuando se utiliza empty() sobre un objeto que está teniendo __get() método, siempre devolverá True.

Cuestiones relacionadas