qiuxis 2016-12-10 14:46:29 299次浏览 0条回复 0 0 0

yii2 行为 behavior (1) —— yii2启示录
yii2 行为 behavior (2) —— yii2启示录
这里再举几个栗子

// backend\controllers\DreamController.php

<?php
namespace backend\controllers;

use Yii;
use yii\web\Controller;
use backend\libs\dream\Doraemon;
use backend\libs\dream\Bear;
use backend\libs\dream\MyClass;
use backend\libs\behaviors\Behavior1;
use backend\libs\behaviors\MyBehavior;

/**
 * Site controller
 */
class DreamController extends Controller
{
    /**
     * Displays homepage.
     *
     * @return string
     */
    public function actionIndex()
    {
        return '';

    }



    public function actionTa()
    {
        $bear       = new Bear();
        $behavior1  = new Behavior1();

        $bear->attachBehavior('beh1',$behavior1);
        //$doraemon->detachBehavior('beh1');
        $bear->eat();

    }


    public function actionTb()
    {
        $doraemon = new Doraemon();
        $doraemon->look();
        $doraemon->eat();
        $doraemon->height = '15cm';
        echo $doraemon->height . PHP_EOL ;
        $doraemon->trigger('wang');

    }

    public function actionTc()
    {
        $myClass = new MyClass();
        $myBehavior = new MyBehavior();

        // Step 3: 将行为绑定到类上
        $myClass->attachBehavior('myBehavior', $myBehavior);

        /**
         * Step 4: 访问行为中的属性和方法,就和访问类自身的属性和方法一样
         * yii\base\Component::__get()
         * http://www.cnblogs.com/dragon16/p/5521199.html
         * @param $name
         * @return mixed
         * 属性的注入
         *
        public function __get($name)
        {
        $getter = 'get' . $name;
        if (method_exists($this, $getter)) {
        return $this->$getter();
        } else {
        // 注意这个 else 分支的内容,正是与 yii\base\Object::__get() 的
        // 不同之处
        $this->ensureBehaviors();
        foreach ($this->_behaviors as $behavior) {
        if ($behavior->canGetProperty($name)) {

        // 属性在行为中须为 public。否则不可能通过下面的形式访问呀。
        return $behavior->$name;
        }
        }
        }
        if (method_exists($this, 'set' . $name)) {
        throw new InvalidCallException('Getting write-only property: ' .
        get_class($this) . '::' . $name);
        } else {
        throw new UnknownPropertyException('Getting unknown property: ' .
        get_class($this) . '::' . $name);
        }
        }
         */
        echo $myClass->property1;

        /**
         * yii\base\Component::__call
         * 方法的注入
         *
        public function __call($name, $params)
        {
        $this->ensureBehaviors();
        foreach ($this->_behaviors as $object) {
        if ($object->hasMethod($name)) {
        return call_user_func_array([$object, $name], $params);
        }
        }
        throw new UnknownMethodException('Calling unknown method: ' .
        get_class($this) . "::$name()");
        }
         */
        echo $myClass->method1();
    }
}

// backend\controllers\BehaviorController.php

<?php
/**
 * Created by sallency.
 * User: sallency
 * Date: 2016/5/31 0031
 * Time: 16:23
 */

namespace backend\controllers;

use backend\libs\behaviors\CtrlBehavior;
use yii\web\Controller;

class BehaviorController extends Controller
{
    const PHP_WEB_EOL = "<br>";

    public function init()
    {
        parent::init(); // TODO: Change the autogenerated stub
    }

    //绑定行为 静态绑定 还有 attachBehavior/attachBehaviors 动态绑定
    public function behaviors()
    {
        return [
            "ctrlBehavior" => [
                "class" => CtrlBehavior::className(),
                "param_1" => "hello",
                "param_2" => "world"
            ]
        ];
    }

    public function actionIndex()
    {
        echo "组件访问行为的属性和方法:" . __METHOD__ . self::PHP_WEB_EOL;
        //使用 __set __get 方法遍历访问行为队列 $_behaviors 中是否有行为对象包含以下属性
        //有则通过此行为对象访问操作属性
        echo "在行为中定义的属性:" . $this->param_1 . "\t" . $this->param_2 . self::PHP_WEB_EOL;
        //使用 __call 方法遍历访问行为队列 $_behaviors 中是否有行为对象包含以下方法
        //有则通过此行为对象访问方法
        $this->extendMethodForCtrl();
        $this->trigger(CtrlBehavior::EVENT_CTRL);
    }
}

// backend\libs\behaviors\Behavior1.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2016/12/9
 * Time: 11:02
 */

namespace backend\libs\behaviors;

use yii\base\Behavior;

class Behavior1 extends Behavior
{
    public $height;
    public function eat()
    {
        echo "heloo i am behavior1 !";
        echo PHP_EOL;
    }

    public function events()
    {
        return [
            'wang' => 'shout',
        ];
    }

    public function shout($event)
    {
        echo 'wang wang wang !';
    }

}

// backend\libs\behaviors\CtrlBehavior.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2016/12/9
 * Time: 21:24
 */

namespace backend\libs\behaviors;

use yii\base\Behavior;
use yii\base\Event;
use yii\rest\Controller;

class CtrlBehavior extends Behavior
{
    const PHP_WEB_EOL   = "<br>";
    const EVENT_CTRL    = 'ctrl' ;
    public $param_1;
    public $param_2;

    /**
     * 行为是为 Controller 做的扩展 故可以注册 Controller 的事件
     * 重载events() 使得在事件触发时,调用行为中的一些方法
     * @return array events for component owner
     */
    public function events()
    {
        // EVENT_BEFORE_ACTION 事件触发时,调用成员函数 handlerBeforeAction
        return [
            Controller::EVENT_BEFORE_ACTION => "handlerBeforeAction",
            Controller::EVENT_AFTER_ACTION  => "handlerAfterAction",
            self::EVENT_CTRL                => "handerMyAction",
        ];
            // 事件 handler("handlerBeforeAction") 可以是以下形式:
            // 字符串,表示行为类的方法,如上面的例就是这种情况。
            // 这个是与事件handler不同的,事件handler中使用字符串时,是表示PHP全局函数,而这里表示行为类内部的方法。
            // 一个对象或类的成员函数,以数组的形式,如 [$object, 'methodName'] 。这个与事件handler是一致的。
            // 一个匿名函数。
    }

    /**
     * event handler
     * 注意 handlerBeforeAction 是行为的成员函数,而不是绑定的类的成员函数。
     * 还要注意,这个函数的签名,要满足事件handler的要求。
     * @param \yii\base\Event $event
     */
    public function handlerBeforeAction(Event $event)
    {
        echo __METHOD__ . self::PHP_WEB_EOL;
        echo '由行为注册的组件事件,传递的$event->sender属性为此组件对象' . self::PHP_WEB_EOL;
        echo "组件的控制器和动作:" . $event->sender->uniqueId . '/' . $event->sender->action->id . self::PHP_WEB_EOL;
        echo self::PHP_WEB_EOL;
    }

    /**
     * event handler
     * @param \yii\base\Event $event
     */
    public function handlerAfterAction(Event $event)
    {
        echo self::PHP_WEB_EOL;
        echo __METHOD__ . self::PHP_WEB_EOL;
        echo '由行为注册的组件事件,传递的$event->sender属性为此组件对象' . self::PHP_WEB_EOL;
        echo "组件的控制器和动作:" . $event->sender->uniqueId . '/' . $event->sender->action->id . self::PHP_WEB_EOL;
    }

    public function handerMyAction(Event $event)
    {
        echo self::PHP_WEB_EOL;
        echo __METHOD__ . self::PHP_WEB_EOL;
        echo "组件的控制器和动作:" . $event->sender->uniqueId . '/' . $event->sender->action->id . self::PHP_WEB_EOL;
    }

    /**
     * 扩展方法 通过 __METHOD__ 我么可以看出这货被组件调用时到底是不是组件的一个方法
     */
    public function extendMethodForCtrl()
    {
        echo "在行为中定义的方法:";
        echo __METHOD__ . self::PHP_WEB_EOL;
    }
}

// backend\libs\behaviors\MyBehavior.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2016/12/9
 * Time: 21:02
 */

namespace backend\libs\behaviors;

use yii\base\Behavior;

class MyBehavior extends Behavior
{
    // 行为的一个属性
    public $property1 = 'This is property in MyBehavior.'.PHP_EOL;

    // 行为的一个方法
    public function method1()
    {
        return 'Method in MyBehavior is called.'.PHP_EOL;
    }

}
    没有找到数据。
您需要登录后才可以回复。登录 | 立即注册
在线
808