💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] # 简介 Yii框架里(我是指@yii目录下,这才是框架)99%的类的祖先类都是`yii\base\Object`或者`yii\base\Component`,这两个类都有相同之处,可以说一个是基础版,一个是加强版 # 特性1: new的时候属性注入 我们先自己定义一个`app\Test`类来继承`yii\base\Object`进行测试 ~~~php namespace app; class Test extends \yii\base\Object{ public $name; public $age; } ~~~ 然后在控制器里玩玩看效果: ~~~php $config = [ 'name' => 'Jay', 'age' => 26, ]; $test = new Test($config); print_r([$test->name, $test->age]); ~~~ # 特性2: 提供空的init方法进行初始化 通常如果我们要在Test的构造方法`__construct`做点事,就无法使用属性注入这个特性了,不信你看看**@yii\\base\\Object.php**的`public function __construct`这里,你怎么能随便重写呢? 那要在new的时候自动执行代码怎么办? 用`public function init(){}`,在Object基类里这个init是一个空方法,用于给子类重写的,\_\_construct后会自动调用init,来来试试 ~~~ namespace app; class Test extends \yii\base\Object{ public $name; public $age; public function init(){ $this->name = 'May'; } } ~~~ 测试 ~~~ $test = new Test(); echo $test->name; //May ~~~ * 重要知识点:**没啥事别重写\_\_construct,建议重写init来做初始化操作** 倒是`__descruct`没这个问题,随你便 # 特性3:getter支持 当继承Object的类有一个`public function getXxx()`方法时,可以直接通过`echo $obj->xxx`来输出`getXxx`方法的返回值,例: ~~~ namespace app; class Test extends \yii\base\Object{ public $sex = '男'; private $_age = 99; public function getAge(){ if($this->sex == '女'){ throw new \Exception('怎么可以向女生问年龄!'); } return $this->_age; } } ~~~ 测试 ~~~ $test = new Test(); echo $test->age; $test->sex = '女'; echo $test->age; ~~~ **总结:关键是方法要public,然后是get开头,get后面的单词就是访问的属性名,方法不能有参数** # 特性4: setter支持 其实这跟特性3是同一个特性,只是我想分开两小节来说,以免一眼看见离下一个大标题那么远,感觉学习量很大的样子,你可以一小点一小点学的~ 与getter一样的逻辑,这个setter就是当你定义了`public function setAge($value)`的时候,执行`$obj->age = 9`就会触发`setAge($value)`方法,而这个$value就是赋过来的值 完善一下Test类: ~~~ namespace app; class Test extends \yii\base\Object{ public $sex = '男'; private $_age = 99; public function getAge(){ if($this->sex == '女'){ throw new \Exception('怎么可以向女生问年龄!'); } return $this->_age; } public function setAge($age){ if($age < 0){ throw new \Exception('无效的年龄'); } $this->_age = $age; } } ~~~ 控制器测试代码: ~~~ $test = new Test(); $test->age = 5; echo $test->age; $test->age = -1; //赋的值有问题,引发异常 ~~~ 总结:方法也要public,命名前缀则是set开头,接收一个`$value`参数处理等号赋的值 getter和setter的好处是让使用这个类的人只管知道有什么属性,细节不关心,要值就访问属性名,要赋值就直接=号赋值,不用调方法传参数 虽然底层通过`__get`和`__set`实现这个特性牺牲了点性能,但我觉得这个牺牲量其实不大,通常带来的好处性价比还是很值得的 # Object的其他与属性相关的方法 除了\_\_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, 都认为是可写。