使用大白话给新手讲讲 Yii2 行为怎么绑定执行的原理 [ 技术分享 ]
学习Yii2肯定要学习行为,新手肯定迷糊,因为我也是刚清醒。不要被这个名字吓唬到,名字随便起的。 行为的目的就是实现了Trait,意思就是说我们自己又一个类,怎么让这个类的对象可以调用另外一个类的方法。 而php的Trait可以通过use来使用另一个类(实际不是另一个类)。
Yii2实现了可以:如下:
// Step 1: 定义一个将绑定行为的类
class MyClass extends yii\base\Component
{
// 空的
}
// Step 2: 定义一个行为类,他将绑定到MyClass上
class MyBehavior extends yii\base\Behavior
{
// 行为的一个属性
public $property1 = 'This is property in MyBehavior.';
// 行为的一个方法
public function method1()
{
return 'Method in MyBehavior is called.';
}
}
$myClass = new MyClass();
$myBehavior = new MyBehavior();
// Step 3: 将行为绑定到类上
$myClass->attachBehavior('myBehavior', $myBehavior);
// Step 4: 访问行为中的属性和方法,就和访问类自身的属性和方法一样
echo $myClass->property1;
echo $myClass->method1();
大概意思就是通过这句话 $myClass->attachBehavior(...)。把行为对象放到一个_behaviors[]数组里存着。 然后$myClass->property1;和$myClass->method1()执行肯定会报错的,但是php有个机制找不到方法的时候会去执行public function call(){...};但是在MyClass里没有public function call(){...} 因为类绑定行为是有要的,就是说你这个MyClass必须继承yii\base\Component 这个类。哎呀,好了。MyClass类没有call(),没事啊,父类Component有啊。于是乎。。 父类的 call()就执行了这个:call()内容如下
foreach ($this->_behaviors as $object) {
if ($object->hasMethod($name)) {
return call_user_func_array([$object, $name], $params);
}
}
循环的$this->_behaviors 就是上面说的把行为放到了这个数组里。然后就这样被执行了。懂了吧。
注意:重写 public function behaviors() 方法一样的处理机制。
自己写了一个小例子:
Behavior.php
<?php
class Behavior
{
}
Component.php
<?php
class Component
{
private $_behaviors;
public function __call($name, $arguments)
{
foreach($this->_behaviors as $object){
if(method_exists($object,$name)){
return call_user_func_array([$object,$name],$arguments);
}
}
}
public function bind($name,$behavior)
{
if(!$behavior instanceof Behavior){
echo 'yii这里会创建一个';
}
$this->_behaviors[] = $behavior;
}
}
上面两个Behavior.php和Component.php是模拟yii2封装的
接下来在创建两个文件
MyClass.php
<?php
class MyClass extends Component//这里继承Component
{
public function pro()
{
echo 'MyClass自己的方法</br>';
}
}
MyBehavior.php
<?php
class MyBehavior extends Behavior //这里继承Behavior
{
public function pro1(){
echo '行为的方法被执行了!</br>';
}
}
然后在index.php写执行代码:
<?php
$b = new MyClass();
$bh = new MyBehavior();
$b->bind('',$bh);
$b->pro(); //这里没疑惑,是执行MyClass自己的方法。
$b->pro1(); //这里就是神奇的MyClass类没有pro1方法却可以调用了。
输出结果:
MyClass自己的方法
行为的方法被执行了!
共 3 条回复
灰太狼
最后登录:2023-07-14
在线时长:76小时17分
- 粉丝28
- 金钱3290
- 威望150
- 积分5550