灰太狼 2019-02-13 16:48:15 2406次浏览 3条回复 1 1 0

学习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自己的方法
     行为的方法被执行了!
觉得很赞
您需要登录后才可以回复。登录 | 立即注册