Как проверить, является ли объект JSON пустым в PHP?

Я читаю данные JSON с PHP и эти данные содержат пустые объекты (например, {}). Поэтому проблема заключается в том, что я должен обрабатывать случай, когда объект пуст по-разному, но я не могу найти достаточно хороший способ сделать проверку. empty(get_object_vars(object)) выглядит слишком страшно и очень неэффективно. Есть ли хороший способ сделать чек?

Сколько объектов вы несериализуете? Если empty(get_object_vars($object)) или кастинг в массив окажется основным замедлением / узким местом, я бы не стал беспокоиться об этом – решение Грега просто отлично.

Я бы предложил использовать $associative флаг $associative при декодировании данных JSON, хотя:

 json_decode($data, true) 

Это расшифровывает объекты JSON как простые старые массивы PHP, а не как объекты stdClass . Затем вы можете проверить пустые объекты с помощью empty() и создать объекты пользовательского класса вместо использования stdClass , что, вероятно, является хорошей идеей в долгосрочной перспективе.

Вы можете передать его в массив (к сожалению, вы не можете сделать это в вызове empty() :

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

Или отбрасывает массив и count() :

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

Попробуйте без использования empty() который:

 get_object_vars($obj) ? TRUE : FALSE; 

В документах PHP мы можем прочитать примечание:

При использовании empty() в недоступных свойствах объекта, при объявлении будет вызываться метод перегрузки __isset() .

Это означает, что при использовании метода empty() для объекта, который имеет метод __get() , он всегда возвращает True.

Я должен был сказать, был ли объект пустым или нет, но мне также пришлось игнорировать частные и защищенные свойства, поэтому я сделал эту небольшую функцию, с которой вы можете это сделать.

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

Я не уверен, что это более или менее эффективно, чем кастинг в массив, но я бы догадался больше. Вы могли бы просто начать цикл объекта, и как только вы найдете что-то, у вас есть ответ и остановка цикла.

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