8

I use this to check if an object has properties,

function objectHasProperty($input){
        return (is_object($input) && (count(get_object_vars($input)) > 0)) ? true : false;
 }

But then I want to check further to make sure all properties have values, for instance,

stdClass Object
        (
            [package] => 
            [structure] => 
            [app] => 
            [style] => 
            [js] => 
        )

Then I want to return false if all the properties have empty values. Is it possible? Any hint and ideas?

3 Answers 3

22

There are several ways of doing this, all the way up to using PHP's reflection API, but to simply check if all public properties of an object are empty, you could do this:

$properties = array_filter(get_object_vars($object));
return !empty($properties);

(The temporary variable $properties is required because you're using PHP 5.4.)

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

Comments

2

For deep inspection and a more advanced handling I'd go for something like the following which is easily extended. Consider it a follow up answer to dev-null-dweller's answer (which is perfectly valid and a great solution).

/**
 * Deep inspection of <var>$input</var> object.
 *
 * @param mixed $input
 *   The variable to inspect.
 * @param int $visibility [optional]
 *   The visibility of the properties that should be inspected, defaults to <code>ReflectionProperty::IS_PUBLIC</code>.
 * @return boolean
 *   <code>FALSE</code> if <var>$input</var> was no object or if any property of the object has a value other than:
 *   <code>NULL</code>, <code>""</code>, or <code>[]</code>.
 */
function object_has_properties($input, $visibility = ReflectionProperty::IS_PUBLIC) {
  set_error_handler(function(){}, E_WARNING);
  if (is_object($input)) {
    $properties = (new ReflectionClass($input))->getProperties($visibility);
    $c = count($properties);
    for ($i = 0; $i < $c; ++$i) {
      $properties[$i]->setAccessible(true);
      // Might trigger a warning!
      $value = $properties[$i]->getValue($input);
      if (isset($value) && $value !== "" && $value !== []) {
        restore_error_handler();
        return true;
      }
    }
  }
  restore_error_handler();
  return false;
}

// Some tests

// The bad boy that emits a E_WARNING
var_dump(object_has_properties(new \mysqli())); // boolean(true)

var_dump(object_has_properties(new \stdClass())); // boolean(false)

var_dump(object_has_properties("")); // boolean(false)

class Foo {

  public $prop1;

  public $prop2;

}

var_dump(object_has_properties(new Foo())); // boolean(false)

$foo = new Foo();
$foo->prop1 = "bar";
var_dump(object_has_properties($foo)); // boolean(true)

Comments

1

Depending on what do you consider as 'empty value' you may have adjust the callback function that removes unwanted values:

function objectHasProperty($input){
    return (
        is_object($input) 
        && 
        array_filter(
            get_object_vars($input), 
            function($val){ 
                // remove empty strings and null values
                return (is_string($val) && strlen($val))||($val!==null); 
            }
        )
    ) ? true : false;
}

$y = new stdClass;
$y->zero = 0;

$n = new stdClass;
$n->notset = null;

var_dump(objectHasProperty($y),objectHasProperty($n));//true,false

7 Comments

empty() will take care of this, all of the following return false if checked with empty(): null, "", and array()
If you'd only want to check against null you would use isset(). Of course that would return true for "" and array(). So in that case you'd have to create your own check (like you did).
Not sure if I understand you correctlly - do you mean passing empty as callback ?
Exactly like George Brighton did it in his answer, this works as expected. For deep inspection of all properties I'd go for a loop as it's much more efficient than anything else.
That's why I'm leaving my answer for other viewers with more demanding requirements.
|

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.