Я читаю данные JSON с PHP и эти данные содержат пустые объекты (например, {}
). Поэтому проблема заключается в том, что я должен обрабатывать случай, когда объект пуст по-разному, но я не могу найти достаточно хороший способ сделать проверку. empty(get_object_vars(object))
выглядит слишком страшно и очень неэффективно. Есть ли хороший способ сделать чек?
Как проверить, является ли объект JSON пустым в PHP?
Ответ 1
Сколько объектов вы несериализуете? Если empty(get_object_vars($object))
или литье в массив окажется основным замедлением/узким местом, я бы не стал беспокоиться об этом - решение Грега просто отлично.
Я бы предложил использовать флаг $associative
при декодировании данных JSON, хотя:
json_decode($data, true)
Это расшифровывает объекты JSON как простые старые массивы PHP, а не как объекты stdClass
. Затем вы можете проверить пустые объекты с помощью empty()
и создать объекты пользовательского класса вместо использования stdClass
, что, вероятно, является хорошей идеей в конечном итоге.
Ответ 2
Вы можете применить его к массиву (к сожалению, вы не можете сделать это при вызове empty()
:
$x = (array)$obj;
if (empty($x))
...
Или применить к массиву и count()
:
if (count((array)$obj))
...
Ответ 3
Попробуйте без использования empty()
, который:
get_object_vars($obj) ? TRUE : FALSE;
В PHP docs мы можем прочитать примечание:
При использовании
empty()
на недоступных объектных свойствах, будет объявлен метод перегрузки__isset()
, если он объявлен.
Это означает, что при использовании empty()
для объекта, имеющего метод __get()
, он всегда будет возвращать True.
Ответ 4
Я должен был сказать, был ли объект пустым или нет, но мне также пришлось игнорировать частные и защищенные свойства, поэтому я сделал эту небольшую функцию, с которой вы можете это сделать.
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;
}
Ответ 5
Я не уверен, что это более или менее эффективно, чем кастинг в массив, но я бы догадался больше. Вы могли бы просто начать цикл объекта, и как только вы найдете что-то, у вас есть ответ и остановка цикла.
function is_obj_empty($obj){
if( is_null($obj) ){
return true;
}
foreach( $obj as $key => $val ){
return false;
}
return true;
}