web-dev-qa-db-fra.com

Comment vérifier si un objet JSON est vide en PHP?

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?

19
vava

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))
    ...
25
Greg

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.

3
kenorb

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;
}
0
Parziphal

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;
}
0
Adam