Я читаю данные 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; }