Je lis les données JSON avec PHP et ces données contiennent des objets vides (comme {}
). Le problème est donc que je dois gérer le cas où l'objet est vide de différentes manières, mais je ne trouve pas le moyen de vérifier le fichier de manière satisfaisante. empty(get_object_vars(object))
semble trop effrayant et très inefficace. Y at-il un bon moyen de faire le chèque?
Combien d'objets désérialisez-vous? À moins que empty(get_object_vars($object))
ou que la diffusion sur array se révèle être un ralentissement majeur/un goulot d'étranglement, je ne m'inquiéterais pas pour cela - la solution de Greg convient parfaitement.
Je suggèrerais toutefois d'utiliser l'indicateur $associative
lors du décodage des données JSON:
json_decode($data, true)
Cela décode les objets JSON en tant que vieux PHP tableaux simples au lieu d'objets stdClass
. Ensuite, vous pouvez rechercher des objets vides à l'aide de empty()
et créer des objets d'une classe définie par l'utilisateur au lieu d'utiliser stdClass
, ce qui est probablement une bonne idée à long terme.
Vous pouvez le lancer dans un tableau (malheureusement, vous ne pouvez pas le faire dans un appel à empty()
:
$x = (array)$obj;
if (empty($x))
...
Ou cast sur un tableau et count()
:
if (count((array)$obj))
...
Essayez sans utiliser empty()
qui est:
get_object_vars($obj) ? TRUE : FALSE;
Sur PHP _ docs nous pouvons lire la note:
Lorsque vous utilisez
empty()
sur des propriétés d'objet inaccessibles, la méthode de surcharge__isset()
sera appelée, si elle est déclarée.
Ce qui signifie que lorsque vous utilisez empty()
sur un objet ayant la méthode __get()
, il renverra toujours True.
Je devais dire si un objet était vide ou non, mais je devais aussi ignorer les propriétés privées et protégées, alors j'ai créé cette petite fonction avec laquelle vous pouvez le faire.
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;
}
Je ne sais pas si cela est plus ou moins efficace que de lancer un tableau, mais je suppose que plus. Vous pouvez simplement commencer à boucler l'objet et dès que vous trouvez quelque chose, vous avez une réponse et vous arrêtez de le lire en boucle.
function is_obj_empty($obj){
if( is_null($obj) ){
return true;
}
foreach( $obj as $key => $val ){
return false;
}
return true;
}