qiuxis 2016-12-11 12:35:41 6114次浏览 2条回复 9 8 0

yii2 事件 event (1) —— yii2启示录

yii2 事件实例 ,最好是放到环境中进行测试,自己修改体会

需求:有这么一个场景 一个屋子里面,有一个人,有一只猫、一只老鼠、一条狗 猫叫了以后老鼠跑了,狗看见了猫,猫也跑了,人看见了把鞋子丢了过去。

这么一个场景如何用YII2的事件机制来表示呢? 猫叫的动作触发了老鼠跑的动作,同时也触发了狗看的动作 而狗看到了猫以后,触发了猫跑这个动作 看到发出的动静,人把鞋子扔了出去

猫的叫声触发了一系列动作

backend\controllers\HouseController

<?php
namespace backend\controllers;

use Yii;
use yii\web\Controller;
use backend\libs\house\Cat;
use backend\libs\house\Dog;
use backend\libs\house\Mouse;
use backend\libs\house\Person;

use yii\base\Event;


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

    public function actionEx1()
    {
        //事件处理器的类型
        $cat1 = new Cat();
        $mouse1 = new Mouse();
        $cat1->on(Cat::EVENT_CAT_EX1, [$mouse1, 'ex1'], '事件处理器的类型:对象方法' );
        $cat1->on(Cat::EVENT_CAT_EX1, 'ex1', '事件处理器的类型:全局函数' );
        $cat1->on(Cat::EVENT_CAT_EX1, ['backend\libs\house\Mouse','ex1'],'事件处理器的类型:静态类方法' );
        $cat1->on(Cat::EVENT_CAT_EX1, function($event){
            echo '匿名函数' . PHP_EOL;
            echo $event->data . PHP_EOL;
        }, '事件处理器的类型:匿名函数');
        $cat1->ex1();
    }

    public function actionEx2()
    {
        //猫叫触发了一些列的动作
        $cat1       = new Cat();
        $mouse1     = new Mouse();
        $dog1       = new Dog();
        $person1    = new Person();
        $cat1->on(Cat::EVENT_CAT_SHOUT, [$mouse1, 'run']); // 猫叫触发了老鼠跑
        $cat1->on(Cat::EVENT_CAT_SHOUT, [$dog1, 'look'] ); // 猫叫触发狗看
        $dog1->on(Dog::EVENT_DOG_LOOK , [$cat1, 'run']); // 狗看触发了猫跑
        $mouse1->on(Mouse::EVEN_MOUSE_RUN, [$person1, 'do']); // 老鼠跑触发了人扔鞋子
        $cat1->shout();
    }

    public function actionEx3()
    {
        // 5只猫触发事件
        $cat1       = new Cat();
        $cat2       = new Cat();
        $cat3       = new Cat();
        $cat4       = new Cat();
        $cat5       = new Cat();
        $mouse1     = new Mouse();

        $cat1->on(Cat::EVENT_CAT_EX1, [$mouse1, 'ex3'], '$cat1 事件处理器的类型:对象方法' );
        $cat2->on(Cat::EVENT_CAT_EX1, [$mouse1, 'ex3'], '$cat2 事件处理器的类型:对象方法' );
        $cat3->on(Cat::EVENT_CAT_EX1, [$mouse1, 'ex3'], '$cat3 事件处理器的类型:对象方法' );
        $cat4->on(Cat::EVENT_CAT_EX1, [$mouse1, 'ex3'], '$cat4 事件处理器的类型:对象方法' );
        $cat5->on(Cat::EVENT_CAT_EX1, [$mouse1, 'ex3'], '$cat5 事件处理器的类型:对象方法' );
        //$cat1->off(Cat::EVENT_CAT_EX1);

        $cat1->ex1();
        $cat2->ex1();
        $cat3->ex1();
        $cat4->ex1();
        $cat5->ex1();
    }

    public function actionEx4()
    {
        // 触发类级别的事件
        $cat1       = new Cat();
        $cat2       = new Cat();
        $cat3       = new Cat();
        $cat4       = new Cat();
        $cat5       = new Cat();
        $mouse1     = new Mouse();

        Event::on(Cat::className(), Cat::EVENT_CAT_EX1, [$mouse1,'ex1'],'5只猫触发类级别的事件');
       // Event::off(Cat::className(), Cat::EVENT_CAT_EX1, [$mouse1,'ex1']);
        $cat1->ex1();
        $cat2->ex1();
        $cat3->ex1();
        $cat4->ex1();
        $cat5->ex1();
    }

    public function actionEx5()
    {
        // 只触发了一次就终止了
        $bool = false ;
        $cat1       = new Cat();
        $mouse1     = new Mouse();
        $dog1       = new Dog();

        $cat1->on(Cat::EVENT_CAT_EX5, [$dog1, 'ex5'], 'dog ex5 !');
        $cat1->on(Cat::EVENT_CAT_EX5, [$mouse1, 'ex5'], 'cat ex5 !', $bool);

        $cat1->ex5();
    }

    public function actionEx6()
    {
        // 触发全局级别事件
        $person = new Person();
        Yii::$app->on('person.bar', function ($event) {
            echo get_class($event->sender);  // 显示 "app\components\Foo"
            echo PHP_EOL;
            echo '触发全局级别事件';
        });
        //Yii::$app->off('person.bar');
        $person->do3();
    }

    public function actionEx7()
    {
        // 事件处理顺序
        $bool = true; // false优先, true推后
        $cat1       = new Cat();
        $dog1       = new Dog();
        $mouse1     = new Mouse();
        $cat1->on(Cat::EVENT_CAT_SHOUT, [$mouse1, 'run']); // 猫叫触发了老鼠跑
        $cat1->on(Cat::EVENT_CAT_SHOUT, [$dog1, 'look'], null, $bool); // 猫叫触发狗看
        $cat1->shout();
    }

    public function actionEx8()
    {
        // 重载了 event 的事件
        $person = new Person();
        $person->on(Person::EVENT_PERSON_DO4, [$person, 'do4']);
        $person->pa();
    }
}


backend\libs\house\Cat.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2016/12/7
 * Time: 12:43
 */

namespace backend\libs\house;
use yii\base\Component;

class Cat extends Component
{
    const EVENT_CAT_SHOUT = 'miao' ;
    const EVENT_CAT_EX1 = 'ex1' ;
    const EVENT_CAT_EX5 = 'ex5' ;

    public function shout()
    {
        echo "miao miao miao ".PHP_EOL;
        $this->trigger(self::EVENT_CAT_SHOUT);
    }

    public function run()
    {
        echo "i am cat, running now !".PHP_EOL;
    }

    public function ex1()
    {
        $this->trigger(self::EVENT_CAT_EX1);
    }

    public function ex5()
    {
        $this->trigger(self::EVENT_CAT_EX5);
    }
}

backend\libs\house\Dog.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2016/12/8
 * Time: 10:30
 */

namespace backend\libs\house;

use yii\base\Component;

class Dog extends Component
{
    const EVENT_DOG_LOOK = 'look';
    public function look()
    {
        echo "i am dog , looking now !".PHP_EOL;
        $this->trigger(self::EVENT_DOG_LOOK);
    }

    public function ex5($event)
    {
        echo $event->data .PHP_EOL;
    }

}

backend\libs\house\Mouse.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2016/12/8
 * Time: 10:32
 */

namespace backend\libs\house;

use yii\base\Component;

class Mouse extends Component
{
    const EVEN_MOUSE_RUN = 'run';
    public function run($event)
    {

        if ($event->data) {
            echo $event->data . PHP_EOL;
        }
        echo "i am mouse, running now !".PHP_EOL;
        $this->trigger(self::EVEN_MOUSE_RUN);
    }

    public function cry($event)
    {
        echo $event->data . PHP_EOL;
        echo 'i am crying!'.PHP_EOL;
        $doself = new static(); // new self();
        $doself->trigger(self::EVEN_MOUSE_RUN);
    }

    public function ex1($event)
    {
        echo $event->data . PHP_EOL;
        var_dump($event);
    }


    public function ex2($event)
    {
        $event->handled = true;
        echo $event->data . PHP_EOL;

        var_dump($event);
    }

    public function ex3($event)
    {
        echo $event->data . PHP_EOL;
    }

    public function ex5($event)
    {
        echo $event->data . PHP_EOL;
        $event->handled = true ;
    }
}

backend\libs\house\MsgEvent.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2016/12/7
 * Time: 18:07
 */

namespace backend\libs\house;
use yii\base\Event;

class MsgEvent extends Event{
    //下面的这三个参数需要在触发事件时传递
    public $dateTime;   // 微博发出的时间
    public $author;     // 微博的作者
    public $content;    // 微博的内容
    public $shoes ;
}

backend\libs\house\Person.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2016/12/8
 * Time: 10:42
 */

namespace backend\libs\house;

use yii\base\Model;

class Person extends  Model
{
    const EVENT_TEST='event_test';
    const EVENT_PERSON_DO4 = "do4" ;
    public function Do($event)
    {
        //print_r($event);
        echo 'I am man , thowing now !'.PHP_EOL;
    }

    public function do3()
    {
        \Yii::$app->trigger('person.bar', new MsgEvent(['sender' => $this]));
    }

    public function do4($event)
    {
        echo 'time: ' . $event->dateTime . ' ,author: ' . $event->author . ' ,content: ' . $event->content . ' ,shoes:' . $event->shoes;
    }

    public function pa()
    {
        $MsgEvent = new MsgEvent();
        $MsgEvent->dateTime = time();
        $MsgEvent->author = 'bingcool';
        $MsgEvent->content = 'hello,everyone';
        $MsgEvent->shoes = 'this is shoes';
        $this->trigger(self::EVENT_PERSON_DO4, $MsgEvent);
    }
}

backend\web\index.php

...
function ex1($parm)
{
    echo $parm->data;
    echo PHP_EOL ;
}
...

觉得很赞
  • 回复于 2016-12-15 09:57 举报

    写的很棒!希望我在拜读几遍之后能体会精髓。

  • 回复于 2017-02-06 10:42 举报

    如果猫叫是一个保存到数据库的操作,恰好这个操作失败了,是不是之后的动作依然继续?

您需要登录后才可以回复。登录 | 立即注册