I'm reading JSON data with PHP and that data contains empty objects (like {}
). So the problem is, I have to handle the case when object is empty in different manner but I can't find good enough way to do the check. empty(get_object_vars(object))
looks too scary and very inefficient. Is there good way to do the check?
-
related: https://stackoverflow.com/q/9412126/3995261 – YakovL Jan 03 '18 at 16:31
5 Answers
How many objects are you unserializing? Unless empty(get_object_vars($object))
or casting to array proves to be a major slowdown/bottleneck, I wouldn't worry about it – Greg's solution is just fine.
I'd suggest using the the $associative
flag when decoding the JSON data, though:
json_decode($data, true)
This decodes JSON objects as plain old PHP arrays instead of as stdClass
objects. Then you can check for empty objects using empty()
and create objects of a user-defined class instead of using stdClass
, which is probably a good idea in the long run.

- 2,187
- 17
- 14
-
1But if you find a plain old PHP array, how do you know if it was encoded from [] or {}? They aren't different in PHP, but they are in JSON. – David Spector Jun 23 '20 at 21:15
You could cast it to an array (unfortunately you can't do this within a call to empty()
:
$x = (array)$obj;
if (empty($x))
...
Or cast to an array and count()
:
if (count((array)$obj))
...

- 316,276
- 54
- 369
- 333
-
-
2I haven't tested it but unless you're having performance problems and have identified this as the bottleneck I don't think it's worth worrying yourself over it. – Greg Sep 07 '09 at 14:43
-
1It's not easy to stop worrying about unnecessary array transformations if you were a C++ programmer most of your life :) It means memory allocation and copying stuff for something that should take just a quick check if a bit is set. – vava Sep 07 '09 at 14:57
-
The count of an array is useless to distinguish [] from {} in JSON. – David Spector Jun 23 '20 at 21:16
Try without using empty()
which is:
get_object_vars($obj) ? TRUE : FALSE;
On PHP docs we can read the note:
When using
empty()
on inaccessible object properties, the__isset()
overloading method will be called, if declared.
Which means when using empty()
on an object which is having __get()
method, it will always return True.

- 155,785
- 88
- 678
- 743
I am not sure if this is more or less effective than casting to an array but I would guess more. You could just start to loop the object and as soon as you find something you have an answer and stop looping.
function is_obj_empty($obj){
if( is_null($obj) ){
return true;
}
foreach( $obj as $key => $val ){
return false;
}
return true;
}

- 6,539
- 3
- 39
- 65
I had to tell if an object was empty or not, but I also had to ignore private and protected properties, so I made this little function with which you can do this.
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;
}

- 6,222
- 4
- 34
- 36