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,可以无须改变类继承关系即可增强一 ...
随机推荐
- java.lang.OutOfMemoryError: Java heap space解决方法
引起java.lang.OutOfMemoryError: Java heap space异常,可能是由JAVA的堆栈设置太小的原因 根据网上的答案大致有以下两种解决方法: 1.在D:/apache- ...
- java-android推送
之前做的推送,考虑了很多,最后因为各个因素,选择了极光的.
- 练习1-16:修改打印最长文本行的程序的主程序main,使之可以打印任意长度的输入行的长度,并尽可能多地打印文本(C程序设计语言 第2版)
该书英文配套答案 Answer to Exercise -, page Revise the main routine of the longest-line program so it will c ...
- hosts文件的一个小发现
今天才发现原来同一个ip可以在hosts文件中配置多个域名.之间老是换一个网站就改一下,现在终于不用这么麻烦了 127.0.0.1 gg.pclady.com.cn 127.0.0.1 gg.pcon ...
- PHP程序员面临的成长瓶颈
作为Web开发中应用最广泛的语言之一,PHP有着大量的粉丝,那么你是一名优秀的程序员吗?在进行自我修炼的同时,你是否想过面对各种各样的问题,我该如何突破自身的瓶颈,以便更好的发展呢? PHP工程师面临 ...
- PL/SQL Developer登入时候报ORA-12638: 身份证明检索失败的解决办法
找到安装目录:C:/oracle/product/10.2.0/db_1/NETWORK/ADMIN 打开sqlnet.ora 在里面找到 SQLNET.AUTHENTICATION_SERVICES ...
- Yii2中的环境配置
默认的Debug配置 在入口文件中 defined ( 'YII_DEBUG' ) or define ( 'YII_DEBUG', true ); defined ( 'YII_ENV' ) or ...
- JQuery图片轮播滚动效果(网页效果--每日一更)
今天,带来的是一个图片的轮播滚动效果! 先来看一下效果展示:亲,请点击这里 原理很简单,设置一个定时器,使图片列表在每隔一段时间后滚动一次.而循环效果,就是在每一滚动的时候,将第一张图片放到最后一张的 ...
- ZooKeeper学习第一期---Zookeeper简单介绍
一.分布式协调技术 在给大家介绍ZooKeeper之前先来给大家介绍一种技术——分布式协调技术.那么什么是分布式协调技术?那么我来告诉大家,其实分布式协调技术主要用来解决分布式环境当中多个进程之间的同 ...
- 一次外企QQ面试
无忧上挂了简历,让个外企的hr约好面试,今天刚面完,整理出来给大家看看.难度不是很大,基本就是Asp.net Mvc 用到的东西,没有问数据库方面的. Part I – Frontend 1. Tr ...