【问题标题】:PHP check whether property exists in object or classPHP检查对象或类中是否存在属性
【发布时间】:2013-01-03 01:49:01
【问题描述】:

我知道 PHP 没有纯对象变量,但我想检查一个属性是否在给定的对象或类中。

$ob = (object) array('a' => 1, 'b' => 12); 

$ob = new stdClass;
$ob->a = 1;
$ob->b = 2;

JS 中, 我可以这样写来检查变量a 是否存在于对象中:

if ('a' in ob)

PHP中,可以做这样的事情吗?

【问题讨论】:

  • 只是提到......当我们做 OOP 时,我们说属性不是变量,就像我们说方法而不是函数一样。

标签: php class variables object parameters


【解决方案1】:

property_exists( mixed $class , string $property )

if (property_exists($ob, 'a')) 

isset( mixed $var [, mixed $... ] )

注意:请注意,如果属性为空,isset() 将返回 false

if (isset($ob->a))

示例 1:

$ob->a = null
var_dump(isset($ob->a)); // false

示例 2:

class Foo
{
   public $bar = null;
}

$foo = new Foo();

var_dump(property_exists($foo, 'bar')); // true
var_dump(isset($foo->bar)); // false

【讨论】:

  • 不一定,如果属性存在,但未定义 isset() 将返回 false。 us3.php.net/manual/en/types.comparisons.php
  • isset() 可以与 empty() 结合来检查属性 值。
  • 虽然 isset() 是错误的答案,但如果您知道警告,它比 property_exists() 快得多
  • 在这种情况下empty() 是更好的解决方案吗? !empty($var) ?
  • @b_dubb no, empty array, 0, false, null, '' all return true by `empty()'
【解决方案2】:

要检查是否存在某些内容,您可以使用 PHP 函数 isset() see php.net。此函数将检查变量是否已设置且不为 NULL。

例子:

if(isset($obj->a))
{ 
  //do something
}

如果你需要检查一个属性是否存在于一个类中,那么你可以使用内置函数property_exists()

例子:

if (property_exists('class', $property)) {
    //do something
}

【讨论】:

    【解决方案3】:

    要检查属性是否存在以及是否为空,您可以使用函数property_exists()

    文档:http://php.net/manual/en/function.property-exists.php

    与 isset() 不同,property_exists() 会返回 TRUE,即使该属性的值为 NULL。

    bool property_exists (mixed $class , string $property)

    例子:

    if (property_exists($testObject, $property)) {
        //do something
    }
    

    【讨论】:

    • 这应该被标记为接受的答案,因为它非常精确地回答了明确的答案。 isset 对于测试对象中是否存在属性没有用处。
    【解决方案4】:

    issetproperty_exists 都不适合我。

    • isset 如果属性存在但为 NULL,则返回 false。
    • property_exists 如果属性是对象的类定义的一部分,则返回 true,即使它已被取消设置。

    我最终选择了:

        $exists = array_key_exists($property, get_object_vars($obj));
    

    例子:

        class Foo {
            public $bar;
    
            function __construct() {
                $property = 'bar';
    
                isset($this->$property); // FALSE
                property_exists($this, $property); // TRUE
                array_key_exists($property, get_object_vars($this)); // TRUE
    
                unset($this->$property);
    
                isset($this->$property); // FALSE
                property_exists($this, $property); // TRUE
                array_key_exists($property, get_object_vars($this)); // FALSE
    
                $this->$property = 'baz';
    
                isset($this->$property); // TRUE
                property_exists($this, $property); // TRUE
                array_key_exists($property, get_object_vars($this));  // TRUE
            }
        }
    

    【讨论】:

    • property_exist + 未设置的属性可能会导致错误行为。这似乎是最安全的方法
    • array_key_exists() 在 php 7.4 中已弃用
    • “不推荐在对象上使用 array_key_exists()”中的关键字是对象。 get_object_vars() 返回一个数组,所以我们还是不错的。
    • @Ali_Hr 不知道您在文档中哪里看到的。 array_key_exists 在 PHP 7.4 中没有被弃用。
    • @Thanh Trung 为什么要取消设置类属性? property_exists 按预期工作。如果您取消设置类属性,则其内部设置为 null。关于文档,如果属性为空,property_exists 也会返回 true。所以我很困惑你的期望。另外值得一提的是,如果实现了神奇的方法 __get,property_exist 不起作用。
    【解决方案5】:

    如果您想知道某个属性是否存在于您定义的类的实例中,只需将property_exists()isset() 结合起来即可。

    public function hasProperty($property)
    {
        return property_exists($this, $property) && isset($this->$property);
    }
    

    【讨论】:

    • 在这里调用 property_exists($this, $property) 有点多余,因为您的代码将始终与单独的 isset($this->$property) 具有相同的结果。
    • 这是对事实的更完整检查,因为isset() 无法告诉您属性是否是类定义的真正成员。稍后我会再次查找以确保。
    • 确实如此,实际类属性的输出将是相同的。如果您有带有__get() 的虚拟属性,更重要的是__isset() 魔术方法,则在某些情况下输出会有所不同。
    【解决方案6】:

    解决方案

    echo $person->middleName ?? 'Person does not have a middle name';

    在 if 语句中显示它的外观,以便更清楚地了解它是如何工作的。

    if($person->middleName ?? false) {
        echo $person->middleName;
    } else {
        echo 'Person does not have a middle name';
    }
    

    说明

    检查某物是否存在的传统 PHP 方法是:

    if(isset($person->middleName)) {
        echo $person->middleName;
    } else {
        echo 'Person does not have a middle name';
    }
    

    或者对于更具体的类方式:

    if(property_exists($person, 'middleName')) {
        echo $person->middleName;
    } else {
        echo 'Person does not have a middle name';
    }
    

    这些在长格式语句中都很好,但在三元语句中它们变得不必要的麻烦,如下所示:

    isset($person->middleName) ? echo $person->middleName : echo 'Person does not have a middle name';

    您也可以像这样只使用三元运算符来实现这一点:

    echo $person->middleName ?: 'Person does not have a middle name';

    但是...如果该值不存在(未设置),它将引发E_NOTICE 并且不是最佳实践。如果值为null,则不会引发异常。

    因此,三元运算符来拯救这是一个简洁的小答案:

    echo $person->middleName ?? 'Person does not have a middle name';

    【讨论】:

    • “猫王操作员”(?:) 不检查属性是否存在!而?? 是空合并运算符。
    • @mickmackusa 如果你真的阅读了我的描述,你会发现我提到过?:
    • 我想我看不出有任何理由在此页面上提及?:,因为标题明确表示:PHP check whether property exists in object or class
    【解决方案7】:

    在对象上使用 array_key_exists() 在 php 7.4 中已弃用

    应该使用 isset() 或 property_exists() 来代替

    参考:php.net

    【讨论】:

      【解决方案8】:

      只要把我的 2 美分放在这里。

      给定以下类:

      class Foo
      {
        private $data;
      
        public function __construct(array $data)
        {
          $this->data = $data;
        }
      
        public function __get($name)
        {
          return $data[$name];
        }
      
        public function __isset($name)
        {
          return array_key_exists($name, $this->data);
        }
      }
      

      会发生以下情况:

      $foo = new Foo(['key' => 'value', 'bar' => null]);
      
      var_dump(property_exists($foo, 'key'));  // false
      var_dump(isset($foo->key));  // true
      var_dump(property_exists($foo, 'bar'));  // false
      var_dump(isset($foo->bar));  // true, although $data['bar'] == null
      

      希望这对任何人都有帮助

      【讨论】:

        【解决方案9】:

        通常我使用某种自定义助手

            /**
             * @param Object $object
             * @param string $property as a string with nested properties 'prop1.nesterdProp.deepvalue'
             * @param mixed $default
             * @return mixed
             */
            function getPropertyOrDefault(Object $object, string $property, $default = null)
            {
                $value = $object;
                $path = explode('.', $property);
                foreach ($path as $prop) {
                    if (is_object($value) && property_exists($value, $prop)) {
                        $value = $value->{$prop};
                    } else {
                        return $default;
                    }
                }
                return $value;
            }
        

        请记住,如果属性为空,您将获得空值且没有默认值。

        顺便说一句,类似的助手也适用于 JS。

        【讨论】:

          猜你喜欢
          • 2019-03-27
          • 2021-12-27
          • 2018-01-01
          • 2020-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多