PHP:如何检查对象的属性是否具有值?

8

我使用这个方法来检查对象是否具有属性:

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

但是我想进一步检查以确保所有属性都有值,例如:

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

如果所有属性都是空值,我希望返回false。这可行吗?有什么提示和想法吗?
3个回答

22

有几种方法可以做到这一点,甚至可以使用PHP的反射API,但为了简单地检查对象的所有公共属性是否为空,您可以这样做:

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

由于使用的是 PHP 5.4 版本,所以需要临时变量$properties


2

如果需要深入检查并进行更高级的处理,我建议使用以下代码,它非常易于扩展。可以将其视为对dev-null-dweller答案(完全有效且是一个很好的解决方案)的后续回答。

/**
 * 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)

1

根据您将什么视为空值,您可能需要调整删除不想要的值的回调函数:

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

1
empty() 将会处理这个问题,如果使用 empty() 进行检查,则以下所有内容都将返回 false: null""array() - Fleshgrinder
如果你只想检查是否为 null,你可以使用 isset()。当然,这会对 ""array() 返回 true。所以在这种情况下,你需要创建自己的检查(就像你所做的那样)。 - Fleshgrinder
就像George Brighton在他的答案中所做的那样,这个代码可以正常工作。如果需要深入检查所有属性,我会选择使用循环,因为它比其他任何方法都更有效。 - Fleshgrinder
正如我在我的回答中所述,一切都取决于一个人认为什么是“空值”。对我来说,false0array()(以及空字符串,尽管我的例子中没有)都是有效的值,在@GeorgeBrighton的解决方案中被视为未设置。 - dev-null-dweller
1
这就是为什么我留下了我的答案,以满足其他有更高要求的观众。 - dev-null-dweller
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接