标签:new xtend extend record ext ebe 代码 strong method
Yii2.0中的一个思想就是组件化的思想,所以、大多数的类都直接或间接的继承自yii\base\Component,而组件的三大功能:属性、事件、行为。
行为的目的是为了方便的扩展一个类的功能,而不需要直接去修改这个类,同时行为中也附带了事件的实现。
1、整体的结构
2、行为
可以无须改变类继承关系即可增强一个已有的组件类功能,当行为附加到组件之后,它将“注入”它的方法和属性到组件,然后可以像访问组件内定义的方法和属性一样访问它们
3、行为如何做到“注入”?
注入一个行为的方式:
attach注入做了什么?
注入完成,怎么生效的(以model为例)?
注:如果同一个组件类中注入了不同的behavior,而不同的behavior有相同的属性,那么使用组件类实例访问属性的时候,返回的 是先attach的behavior,因为在getter中是foreach循环$_behaviors,存在则return,循环终止
同理:
不手动attachBehavior,怎么做?
行为中的事件?
所以在事件绑定方法on和事件触发方法trigger方法中,都首先调用了$this->ensureBehaviors()方法,来保证行为中的事件也已经调用绑定成功了
4、简单的示例代码
//Yii中的祖先类
class Object
{
//魔术方法,实现getter
public function __get($name)
{
$getter = ‘get‘.$name;
if(method_exists($this, $getter)){
return $this->$getter();
}
}
//判断是否有对应的getter方法 || 直接有相应的属性
public function canGetProperty($name, $checkVars = true)
{
return method_exists($this, ‘get‘ . $name) || $checkVars && property_exists($this, $name);
}
}
//行为基类
class Behavior extends Object
{
//行为注册到的那个组件类的引用
public $owner;
//行为附加操作
public function attach($owner)
{
$this->owner = $owner;
//事件的处理
foreach($this->events() as $event => $handler){
//$this->owner->on($event, $handler);
}
}
//behavior中可以定义events,attach中会进行事件的绑定
public function events()
{
return [];
}
}
//组件基类
class Component extends Object
{
public $_behaviors = [];
//__get
public function __get($name)
{
$getter = ‘get‘.$name;
if(method_exists($this, $getter)){
return $this->$getter();
}else{
$this->ensureBehaviors();
foreach($this->_behaviors as $behavior){
return $behavior->$name;
}
}
}
//读取相应组件中的behaviors配置,调用attachBehaviorInternal,将当前组件行为保存到$_behaviors
public function ensureBehaviors()
{
if($this->_behaviors === null){
$this->_behaviors = [];
foreach($this->behaviors() as $name => $behavior){
$this->attachBehaviorInternal($name, $behavior);
}
}
}
//将当前组件对象保存传递给行为类中了owner,在组件类中保存所有的行为
public function attachBehaviorInternal($name, $behavior)
{
if(!($behavior instanceof Behavior)){
//根据配置创建behavior对象
}
if(is_int($name)){
$behavior->attach($this);
$this->_behaviors[] = $behavior;
}else{
$behavior->attach($this);
$this->_behaviors[$name] = $behavior;
}
return $behavior;
}
}
//test 测试要使用的行为的类必须继承Component
class TestModel extends Component
{
public $test = ‘test‘;
}
class MyBehavior extends Behavior
{
public $mybehavior = ‘get my behavior success‘;
public function getMybehavior()
{
return $this->mybehavior;
}
}
$model = new TestModel();
$myBehavior = new MyBehavior();
$model->attachBehaviorInternal(‘myBehavior‘, $myBehavior);
echo $model->mybehavior;
//输出
//get my behavior success
标签:new xtend extend record ext ebe 代码 strong method
原文地址:https://www.cnblogs.com/skyfynn/p/8921058.html