我正在使用PHP读取JSON数据,其中的数据包含了空对象(例如{}
)。因此问题是,我必须以不同的方式处理对象为空的情况,但我找不到足够好的方法来进行检查。 empty(get_object_vars(object))
看起来太可怕且效率低下。有没有更好的方法来进行检查?
您要反序列化多少个对象?除非empty(get_object_vars($object))
或将其强制转换为数组证明是主要的减速/瓶颈,否则我不会担心 - Greg的解决方案很好。
我建议在解码JSON数据时使用$associative
标志:
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;
这意味着当在具有当使用
empty()
函数检查不可访问的对象属性时,如果已声明,则会调用__isset()
重载方法。
__get()
方法的对象上使用empty()
函数时,它将始终返回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;
}