Yii2的深入学习--yii\base\Object 类
之前我们说过 Yii2 中大多数类都继承自 yii\base\Object,今天就让我们来看一下这个类。
Object 是一个基础类,实现了属性的功能,其基本内容如下:
<?php
namespace yii\base; use Yii; /**
* Object 是一个基础类,实现了属性的功能
* Yii最基础的类,大多数类都继承了该类
*/
class Object implements Configurable
{
/**
* 获取静态方法调用的类名。返回类的名称,如果不是在类中调用则返回 FALSE。
*/
public static function className()
{
...
} /**
* Constructor.
*/
public function __construct($config = [])
{
...
} /**
* 初始化对象
*/
public function init()
{
} /**
* 魔术方法,实现 getter
*/
public function __get($name)
{
...
} /**
* 魔术方法,实现 setter
*/
public function __set($name, $value)
{
...
} /**
* 魔术方法,实现 isset,基于 getter 实现,有 getter 方法的属性才算存在
*/
public function __isset($name)
{
...
} /**
* 魔术方法,实现 unset,基于 setter 实现,有 setter 方法的属性才能 unset 掉
*/
public function __unset($name)
{
...
} /**
* Calls the named method which is not a class method.
*/
public function __call($name, $params)
{
...
} /**
* 检查对象或类是否具有 $name 属性,如果 $checkVars 为 true,则不局限于是否有 getter/setter
*/
public function hasProperty($name, $checkVars = true)
{
...
} /**
* 检查对象或类是否能够获取 $name 属性,如果 $checkVars 为 true,则不局限于是否有 getter
*/
public function canGetProperty($name, $checkVars = true)
{
...
} /**
* 检查对象或类是否能够设置 $name 属性,如果 $checkVars 为 true,则不局限于是否有 setter
*/
public function canSetProperty($name, $checkVars = true)
{
...
} /**
* 检查对象或类是否具有 $name 方法
*/
public function hasMethod($name)
{
...
}
}
如果想看详细的注释的话,可以访问 https://github.com/ReadCode/yii2-2.0.3-annotated/blob/master/framework/base/Object.php
从上面的内容中,我们可以看到 Object 类重写了 __get 和 __set 方法,下面我们来详细看下这两个方法:
/**
* Returns the value of an object property.
*
* Do not call this method directly as it is a PHP magic method that
* will be implicitly called when executing `$value = $object->property;`.
*
* 魔术方法,实现 getter
*
* @param string $name the property name
* @return mixed the property value
* @throws UnknownPropertyException if the property is not defined
* @throws InvalidCallException if the property is write-only
* @see __set()
*/
public function __get($name)
{
$getter = 'get' . $name;
if (method_exists($this, $getter)) {
// 对象存在 $getter 方法,就直接调用
return $this->$getter();
} elseif (method_exists($this, 'set' . $name)) {
// 如果存在 'set' . $name 方法,就认为该属性是只写的
throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
} else {
// 否则认为该属性不存在
throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
}
} /**
* Sets value of an object property.
*
* Do not call this method directly as it is a PHP magic method that
* will be implicitly called when executing `$object->property = $value;`.
*
* 魔术方法,实现 setter
*
* @param string $name the property name or the event name
* @param mixed $value the property value
* @throws UnknownPropertyException if the property is not defined
* @throws InvalidCallException if the property is read-only
* @see __get()
*/
public function __set($name, $value)
{
$setter = 'set' . $name;
if (method_exists($this, $setter)) {
// 对象存在 $setter 方法,就直接调用
$this->$setter($value);
} elseif (method_exists($this, 'get' . $name)) {
// 如果存在 'get' . $name 方法,就认为该属性是只读的
throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
} else {
// 否则认为该属性不存在
throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
}
}
基于上面的代码,我们可以看到,如果访问一个 Object 对象的某个属性, Yii会调用名为 get属性名() 的函数。如, SomeObject->Foo , 会自动调用 SomeObject->getFoo()。 如果修改某一属性,会调用相应的setter函数。 如, SomeObject->Foo = $someValue ,会自动调用 SomeObject->setFoo($someValue) 。
以 SomeObject 的 Foo 为例,如果只存在 getFoo() 方法,那它就是只读的,如果只存在 setFoo() 方法,那它就是只写的,只有两个方法都存在的时候才是既可读又可写的。
需要注意的一点是只有在读取和写入对象的一个不存在的成员变量时, __get() __set() 会被自动调用。 如果 Foo 是一个 public 的属性就不会经过 __get() 和 __set() 方法了。
所以通常属性是 private 的,举个例子如下:
class User extends yii\base\Object
{
private $_name; public function getName()
{
return $this->_name;
} public function setName($name)
{
$this->_name = trim($name);
}
}
我们还可以在 get 和 set 方法中做一些特殊的处理。
除了 __get() __set() 之外, yii\base\Object 还提供了以下方法便于使用属性:
- __isset() 用于测试属性值是否不为 null ,在 isset($object->property) 时被自动调用。 注意该属性要有相应的 getter。
- __unset() 用于将属性值设为 null ,在 unset($object->property) 时被自动调用。 注意该属性要有相应的 setter。
- hasProperty() 用于测试是否有某个属性。即,定义了 getter 或 setter。 如果 hasProperty() 的参数 $checkVars = true (默认为true), 那么只要具有同名的成员变量也认为具有该属性,如前面提到的 public $title 。
- canGetProperty() 测试一个属性是否可读,参数 $checkVars 的意义同上。只要定义了 getter,属性即可读。 同时,如果 $checkVars 为 true 。那么只要类定义了成员变量,不管是 public, private 还是 protected, 都认为是可读。
- canSetProperty() 测试一个属性是否可写,参数 $checkVars 的意义同上。只要定义了 setter,属性即可写。 同时,在 $checkVars 为 ture 。那么只要类定义了成员变量,不管是 public, private 还是 protected, 都认为是可写。
对 Yii2 源码有兴趣的同学可以关注项目 yii2-2.0.3-annotated,现在在上面已经添加了不少关于 Yii2 源码的注释,之后还会继续添加~
有兴趣的同学也可以参与进来,提交 Yii2 源码的注释。
Yii2的深入学习--yii\base\Object 类的更多相关文章
- Yii2的深入学习--yii\base\Event 类
根据之前一篇文章,我们知道 Yii2 的事件分两类,一是类级别的事件,二是实例级别的事件.类级别的事件是基于 yii\base\Event 实现,实例级别的事件是基于 yii\base\Compone ...
- 老刘 Yii2 源码学习笔记之 Component 类
类图关系 属性与方法 class Component extends BaseObject { private $_events = []; private $_eventWildcards = [] ...
- 1.9(java学习笔记)object类及toString()与equals()方法
object类 java中objec是所有类公共的父类,一个类只要没有明显的继承某一类,那么它就是继承object类. 例如 class Person {......};和class Person e ...
- JavaScript学习总结(十一)——Object类详解
一.Object类介绍 Object类是所有JavaScript类的基类(父类),提供了一种创建自定义对象的简单方式,不再需要程序员定义构造函数. 二.Object类主要属性 1.constructo ...
- 老刘 Yii2 源码学习笔记之 Action 类
Action 的概述 InlineAction 就是内联动作,所谓的内联动作就是放到controller 里面的 actionXXX 这种 Action.customAction 就是独立动作,就是直 ...
- 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:Object类
class Demo{ // 定义Demo类,实际上就是继承了Object类 }; public class ObjectDemo01{ public static void main(String ...
- 老刘 Yii2 源码学习笔记之 Module 类
关系类图 从上图可以看出 Application 类继承了 Module,在框架中的是非常重要角色. 加载配置 public function setModules($modules) { forea ...
- Java学习笔记之——Object类
所有类的祖先 如果一个类没有显式继承,则继承Object 每一个类都直接或间接的是Object的子类 相关API: protected Objectclone() 创建并返回此对象的副本. boole ...
- Yii2的深入学习--行为Behavior
我们先来看下行为在 Yii2 中的使用,如下内容摘自 Yii2中文文档 行为是 [[yii\base\Behavior]] 或其子类的实例.行为,也称为 mixins,可以无须改变类继承关系即可增强一 ...
随机推荐
- C++内存对齐的理解
程序编译器对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式. 编译器中提供了#pragma pack(n)来设 ...
- 用Yaml文件进行元素管理【转】
原文:http://www.cnblogs.com/milanmi/p/4636503.html 如界面有一个按钮,id号是test.如果进行对象化的话,就是test.click就可以了.不用每次都要 ...
- solr&lucene3.6.0源码解析(四)
本文要描述的是solr的查询插件,该查询插件目的用于生成Lucene的查询Query,类似于查询条件表达式,与solr查询插件相关UML类图如下: 如果我们强行将上面的类图纳入某种设计模式语言的话,本 ...
- Keeping Async Methods Alive
Consider a type that will print out a message when it’s finalized, and that has a Dispose method whi ...
- 安利eclipse插件之log4E
敲完代码之后,据说要加注释.加log:OTL~~~~~~~~,在我仰天长叹之际,师父发给我了一个插件压缩包,解压-->拷贝-->重启-->了事.安装方法已经如此之便捷,简直是我辈懒癌 ...
- wlan-mcs来自百度百科
工作原理 802.11n射频速率的配置通过MCS(Modulation and Coding Scheme,调制与编码策略)索引值实现.MCS调制编码表是802.11n为表征WLAN的通讯速率而提出的 ...
- 一次与51aspx客服MM谈话 -- 坑是怎么发展的
GG从发布以来,我每次版本更新都会同步到51aspx源码网站,这次在同步更新GG V3.2版本到51aspx时,出了点小状况: 上传3.2版本几个小时后,我再次上去查看,发现其状态变成了“退回”,于是 ...
- Ubuntu Desktop基本办公环境搭建
Ubuntu Desktop基本办公环境搭建 一如前面所强调的, linux系统是面向开发人员友好的,而对office办公人员并不友好 . 如果是重度的office办公需求人员,不建议使用linux ...
- 【读书笔记】javascript 继承
在JavaScript中继承不像C#那么直接,C#中子类继承父类之后马上获得了父类的属性和方法,但JavaScript需要分步进行. 让Brid 继承 Animal,并扩展自己fly的方法. func ...
- 防止开发人员获取到敏感数据(SQL Server的数据加密简介)
背景 有时候,我们还真的会碰到这样的需求:防止开发人员获取到敏感数据.也许你觉得很简单,把开发和运营分开不就可以了吗?是的,如果公司有专门的运营团队的话,但对于很多小公司来说,几个人的开发团队就兼顾了 ...