Yii2之属性

  一直以来,在我的理解中,类的成员变量和属性就是同一个东西,直到看了《深入理解Yii2.0才明白,类的成员变量和属性其实不是同一个概念,成员变量是就类的结构构成而言的概念,而属性是就类的功能逻辑而言的概念,而且两者没有必然的对应关系。

        类的成员变量有publicprotectedprivate三种类型,其中public类型的成员变量可以视为可读可写的属性,而另外两种类型的成员变量都不是属性,因为属性应该是可以在类外面进行访问的。

        Yii2.0中,yiiaseObject类通过PHP的魔术方法__get()__set()来提供对属性的支持,源码如下:

public function __get($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {//存在对应的getter方法
        return $this->$getter();
    } elseif (method_exists($this, 'set' . $name)) {//只写属性
        throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
    } else {//属性不存在
        throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
    }
}
public function __set($name, $value)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {//存在对应的setter方法
        $this->$setter($value);
    } elseif (method_exists($this, 'get' . $name)) {//只读属性
        throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
    } else {//属性不存在
        throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
    }
}

  在yii2.0中,如果一个类需要支持属性,只要继承yiiaseObject类即可,以下举例说明:

class user extends yiiaseObject {
         public $name;
         private $addr;
         private $age;
         public function getAddress() {
                  return $this->addr;
         }
}

  这是一个很简单的类,根据类的成员变量和属性的概念可知,以上这个类中有三个成员变量:$name$addr$age,两个属性:$nameaddress。其中$name是可读可写属性,而address是只读属性,因为只存在getter方法而没有对应的setter方法。

  假如我们在user类外面创建一个对象$user,通过$user->address来读取user类的address属性的时候,其实是遍历了一下user类的所有成员变量,没有找到address属性对应的成员变量的时候,再去调用__get()方法看看是否存在对应的getter方法,有则调用它。可以看到,当类的某个属性没有对应的成员变量的时候,通过$user->address这种方式来访问属性虽然比较方便但效率是比较低的,而使用$user->getAddress() 直接调用getter方法访问属性则可以省去遍历类成员变量的过程,比较高效。

        除了__get()__set()之外,yiiaseObject类还提供了与属性相关的其他方法:

__isset():判断属性是否不为null

__unset():将属性值设置为null

hasProperty():判断是否存在某个属性。

canGetProperty():判断某个属性是否可读。

canSetProperty():判断某个属性是否可写。

         yii2.0中,创建一个对象的时候,怎么给对象的所有属性赋值呢?Yii2.0提供了一个统一的配置对象的方式,那就是使用一个键值对形式的配置数组。那么yii2.0又是怎么支持这种配置方式的呢?通过查看源码可以看到,yiiaseObject类的构造函数__construct()中调用了Yii::configure()方法,该方法源码如下:

public static function configure($object, $properties)
{
    foreach ($properties as $name => $value) {
        $object->$name = $value;
    }

    return $object;
}

  其实很简单,就是遍历配置数组,配置数组的键名为对象的属性名,对应的值则作为属性值,逐一进行赋值。至于当对象的属性是对象或数组时,赋值操作该怎么进行就是setter函数的事了。

 

原文地址:https://www.cnblogs.com/wujuntian/p/7491725.html