zoukankan      html  css  js  c++  java
  • 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函数的事了。

     

  • 相关阅读:
    A. Generous Kefa
    1031 骨牌覆盖
    1074 约瑟夫环 V2
    1073 约瑟夫环
    1562 玻璃切割
    Ants
    1024 矩阵中不重复的元素
    1014 X^2 Mod P
    1135 原根
    1010 只包含因子2 3 5的数
  • 原文地址:https://www.cnblogs.com/wujuntian/p/7491725.html
Copyright © 2011-2022 走看看