28

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?

1

5 Answers 5

36

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.

Sign up to request clarification or add additional context in comments.

1 Comment

But 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.
29

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))
    ...

4 Comments

Isn't it the same as with get_object_vars? I.e. not really efficient? :)
I 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.
It'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.
The count of an array is useless to distinguish [] from {} in JSON.
4

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.

Comments

0

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.