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

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

在Yii2.0中,yii\base\Object类通过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中,如果一个类需要支持属性,只要继承yii\base\Object类即可,以下举例说明:

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

  这是一个很简单的类,根据类的成员变量和属性的概念可知,以上这个类中有三个成员变量:$name、$addr、$age,两个属性:$name、address。其中$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()方法,该方法源码如下:

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

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

Yii2之属性的更多相关文章

  1. yii2知识点理解(成员属性)

    yii2成员属性 成员变量类似于public $a; 成员属性类似于 public function a(){} 成员变量是就类的结构构成而言的概念,而属性是就类的功能逻辑而言的概念 成员属性应用: ...

  2. Yii2之组件的注册与创建

    今天本来打算研究一下yii2.0的AR模型的实现原理,然而,计划赶不上变化,突然就想先研究一下yii2.0的数据库组件创建的过程.通过对yii源码的学习,了解了yii组件注册与创建的过程,并发现原来y ...

  3. Yii2基本概念之——配置(Configurations)

    在Yii中创建新对象或者初始化已经存在的对象广泛的使用配置,配置通常包含被创建对象的类名和一组将要赋值给对象的属性的初始值,这里的属性是Yii2的属性.还可以在对象的事件上绑定事件处理器,或者将行为附 ...

  4. jqu

    1 /*2 * 说明:3 * 本源代码的中文注释乃Auscarlin呕心沥血所作.旨在促进jQuery的传播以及向广大jQuery爱好者提供一个进阶4 *的途径,以让各位更加深入地了解jQuery,学 ...

  5. Yii2基本概念之——属性(property)

    学习任何一门学问,往往都是从起基本的概念学起.万丈高楼平地起,这些基本概念就是高楼的基石,必须做详尽的分析.我们知道,Yii2是一款脉络清晰的框架,理顺了基础的概念和基本功能,学习更高级和复杂的功能就 ...

  6. Yii2给数据库表添加字段后对应模型无法识别到该属性的原因和解决办法

    Yii2给数据库表添加字段后对应模型无法识别到该属性的原因和解决办法 应为数据库表的结构被缓存了.删除runtime文件夹或者执行 //清理指定表结构缓存数据 Yii::$app->db-> ...

  7. yii2:属性

    yii2:属性 在 PHP 中,类的成员变量也被称为属性(properties). 以Foo.php类文件为例: 继承yii\base\Object类(基于类内的 getter 和 setter(读取 ...

  8. Yii2 提供可以用属性的方式去获取类的一个方法

    刚开始用 Yii 的小朋友可能对下面的写法非常疑惑: public function actionIndex() { $user = User::find()->where(['name'=&g ...

  9. [moka同学笔记]Yii2.0给一张表中增加一个属性

    1.model中建立关联 public function getUser(){ return$this->hasOne(User::className(),['id'=>'uid']) ; ...

随机推荐

  1. Ajax跨域问题的出现和解决

    什么是跨域? 1).请求是执行过去了,但是响应的数据拿不到 2).浏览器有一个安全限制叫同源策略(针对ajax请求): 从http://localhost:80/member/apply.html页面 ...

  2. 如何选择适合的前端UI框架

    根据近几年前端框架的热门,在前端开发框架不断更新与交换的时代,每一年都有黑马出现,是否适合自己开发的项目就不得而知了,只有认真的了解之后才能知道,这里主要给大家说一下如何选择适合旅游的前端UI框架?相 ...

  3. Flask-WTF 创建表单P2

    表单安全 无需任何配置,FlaskForm将提供具有CSRF(Cross-site request forgery,也被称为one-click attack 或者session riding,通常缩写 ...

  4. css样式引入优先级?

    css中的优先级讲的有 1.选择器的优先级. 2.样式引入的优先级. 今天要研究的是样式引入的优先级.网上又很多答案都是如下的,但是真的是这样的吗,让我们来探一探究竟是如何. 四种样式的优先级别是:行 ...

  5. 【京东账户】——Mysql/PHP/Ajax爬坑之购物车列表显示

    一.引言 做京东账户项目中的购物车模块,功能之二是购物车列表显示.要用到的是Apach环境,Mysql.PHP以及Ajax. 二.小功能-点击“去购物车结算” 小坑:Ajax动态生成的不能直接绑定,因 ...

  6. 深入理解计算机系统chapter9

    从概念上来讲:虚拟存储器被组织为一个存放在磁盘上的N个连续的字节大小的单元组成的数组. 磁盘上数组的内容被缓存到主存中 1. 读写内存的安全性 物理内存本身是不限制访问的,任何地址都可以读写,而操作系 ...

  7. HDFS概述(5)————HDFS HA

    HA With QJM 目标 本指南概述了HDFS高可用性(HA)功能以及如何使用Quorum Journal Manager(QJM)功能配置和管理HA HDFS集群. 本文档假设读者对HDFS集群 ...

  8. 化繁为简 经典的汉诺塔递归问题 in Java

    问题描述   在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔.不论白天黑 ...

  9. Thirft框架快速入门

    Thrift介绍1.什么是thrift?thrift早期由facebook内部团队开发,主要用于实现跨语言间的方法调用,属于远程方法调用的一种,后开源纳入apache中,成为了apache thrif ...

  10. Spark版wordcount,并根据词频进行排序

    import org.apache.spark.{SparkConf, SparkContext}/** * Created by loushsh on 2017/10/9. */object Wor ...