Yii2之属性

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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中,如果一个类需要支持属性,只要继承yii\base\Object类即可,以下举例说明:

1
2
3
4
5
6
7
8
class user extends yii\base\Object {
         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()之外,yii\base\Object类还提供了与属性相关的其他方法:

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

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

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

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

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

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

1
2
3
4
5
6
7
8
public static function configure($object, $properties)
{
    foreach ($properties as $name => $value) {
        $object->$name = $value;
    }
 
    return $object;
}

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

 

posted @   疯一样的狼人  阅读(1303)  评论(1编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
历史上的今天:
2016-09-07 MySQL数据类型
2015-09-07 C++数组做参数
点击右上角即可分享
微信分享提示