yii2 event实例(基于restful风格) [ 新手入门 ]
本案例参考 http://www.yiichina.com/topic/6690 而来, 感谢作者的贡献
- 需求:有这么一个场景:
- 一个屋子里面,有一个人,有一只猫、一只老鼠、一条狗
- 猫叫了以后老鼠跑了,狗看见了猫,猫也跑了,人看见了把鞋子丢了过去。
- 这么一个场景如何用restful风格的YII2的事件机制来表示呢?
- 分析:
- 猫叫的动作触发了老鼠跑的动作,同时也触发了狗看的动作
- 而狗看到了猫以后,触发了猫跑这个动作
看到发出的动静,人把鞋子扔了出去
猫的叫声触发了一系列动作
* 现在把这个场景具体化:
* 猫叫了(当插入一条数据成功后,说明猫叫成功了), 触发了老鼠跑(插入一条数据),同时触发了狗看(插入一条数据)
* 而狗看(插入一条数据成功后,说明狗看猫成功了)到了猫以后,触发了猫跑(再次插入一条数据)这个动作,
* 看到发出的动静(老鼠跑:插入一条数据成功后,说明人看到),人把鞋子扔了出去(插入一条数据)
数据表如下:
注意: 该sql适用于mysql数据库
create table test_house_event (
id int unsigned not null primary key auto_increment,
type tinyint unsigned not null comment '类型:1 猫, 2 老鼠, 3 狗, 4 人',
content varchar (100) not null comment '动作内容',
createdAt int unsigned not null,
) engine=innodb auto_increment=1 default charset=utf8 collate=utf8_general_ci comment='test_house_event';
上代码: ///////////////////////////////////////// 发起一条请求, 创建一条'猫叫了'的数据记录, 用来触发相应的事件: // 前段请求部分 ` $data = [
'content' => date('Y-m-d H:i:s') . '我是一只猫, 我叫唤了一声: 喵~'
]; $uri = xxx . '/devTestEvent/testEvent/house'; $.post($uri, $data, function() {
// 返回响应的数据, 进行处理
}) `
///////////////////////////////////////// php部分: /////////////////////////////////////////
1.Controller: HouseController.php:
` <?php
/**
*需求:有这么一个场景:
*一个屋子里面,有一个人,有一只猫、一只老鼠、一条狗
*猫叫了以后老鼠跑了,狗看见了猫,猫也跑了,人看见了把鞋子丢了过去。
*这么一个场景如何用YII2的事件机制来表示呢?
*分析:
*猫叫的动作触发了老鼠跑的动作,同时也触发了狗看的动作
*而狗看到了猫以后,触发了猫跑这个动作
*看到发出的动静,人把鞋子扔了出去
*
*猫的叫声触发了一系列动作
*
*现在把这个场景具体化:
*猫叫了(当插入一条数据成功后,说明猫叫成功了), 触发了老鼠跑(插入一条数据),同时触发了狗看(插入一条数据)
*而狗看(插入一条数据成功后,说明狗看猫成功了)到了猫以后,触发了猫跑(再次插入一条数据)这个动作,
*看到发出的动静(老鼠跑:插入一条数据成功后,说明人看到),人把鞋子扔了出去(插入一条数据)
*/
namespace webserver\controllers\devTestEvent\testEvent;
use common\models\devTestEvent\testEvent\BaseModel; use yii\rest\ActiveController use webserver\models\devTestEvent\testEvent\Cat;
class HouseController extends ActiveController {
public $modelClass = Cat::class;
public function actionIndex()
{
return BaseModel::find()->asArray()->all();
}
} ` /////////////////////////////////////////////////////
2.Model: BaseModel.php: ` <?php
/**
* testEvent BaseModel:基础Model,该案例所有Model都继承该类
*/
namespace common\models\devTestEvent\testEvent;
use yii\behaviors\TimestampBehavior; use yii\db\ActiveRecord;
/**
* Class BaseModel
* @package common\models\devTestEvent\testEvent
*/
class BaseModel extends ActiveRecord
{
/**
* 类型: 猫
*/
public const TYPE_CAT = 1;
/**
* 类型: 老鼠
*/
public const TYPE_MOUSE = 2;
/**
* 类型: 狗
*/
public const TYPE_DOG = 3;
/**
* 类型: 人
*/
public const TYPE_PERSON = 4;
/**
* 数据表名
* @inheritdoc
*/
public static function tableName()
{
return 'test_house_event';
}
/**
* 校验规则
* @inheritdoc
*/
public function rules()
{
return [
['type', 'required'],
['type', 'in', 'range' => [self::TYPE_CAT, self::TYPE_MOUSE, self::TYPE_DOG, self::TYPE_PERSON]],
[['content'], 'string'],
[['content'], 'trim'],
];
}
/**
* 开启事务处理机制
* @inheritdoc
*/
public function transactions()
{
return [
self::SCENARIO_DEFAULT => self::OP_ALL,
];
}
public function behaviors()
{
return [
[
'class' => TimestampBehavior::class,
'createdAtAttribute' => 'createdAt',
'updatedAtAttribute' => false,
],
];
}
}
Cat.php
<?php
namespace webserver\models\devTestEvent\testEvent;
use common\models\devTestEvent\testEvent\BaseModel; use webserver\exceptions\Exception; use webserver\event\devTestEvent\testEvent\CatEvent; use webserver\event\devTestEvent\testEvent\DogEvent;
/**
* Class Cat
*
* @property int $id
* @property int $type
* @property string $content
* @property int $createdAt
*
* @package webserver\models\devTestEvent\testEvent
*/
class Cat extends BaseModel
{
/**
* event: 猫叫了
*/
public const EVENT_CAT_SHOUT = 'shout';
/**
* 是否绑定自定义事件: is Binding User Defined Event
* @var bool
*/
public $isBindingUDE = true;
public function init()
{
parent::init();
$this->type = self::TYPE_CAT; // `type`默认值为猫
}
/**
* 事件handler: 狗看了一眼猫后的事件处理器
* @param DogEvent $event
* @throws EzException
*/
public function run(DogEvent $event)
{
$model = new self();
$model->content = date('Y-m-d H:i:s') . "我是那只猫,刚才叫了一声, 结果那只狗(#{$event->dogId})看了我一眼,所以我跑了";
$model->isBindingUDE = false; // 该属性会在save之前和save之后使用,目的: 多次save时判断是否绑定事件, 只有猫叫了才会绑定和触发一系列事件,猫的其他动作不会绑定和触发事件
$result = $model->save();
if (!$result) {
// 该处可自定义Exception
throw new Exception(Exception::ERROR_TRANSACTION_ERROR, '跑慢了, 被狗逮着了, 喵~');
}
}
public function beforeSave($insert)
{
if ($this->isBindingUDE) {
// 猫叫了(当插入一条数据成功后,说明猫叫成功了), 触发了老鼠跑(插入一条数据),同时触发了狗看(插入一条数据)
$this->on(self::EVENT_CAT_SHOUT, [Mouse::class, 'run']);
$this->on(self::EVENT_CAT_SHOUT, [Dog::class, 'look']);
}
return parent::beforeSave($insert);
}
public function afterSave($insert, $changedAttributes)
{
parent::afterSave($insert, $changedAttributes);
if ($insert && $this->isBindingUDE) {
// 插入一条数据成功(猫叫成功了)后, 并且绑定了自定义事件, 触发事件
$catEvent = new CatEvent();
$catEvent->catId = $this->id;
$this->trigger(self::EVENT_CAT_SHOUT, $catEvent);
}
}
} `
Mouse.php: ` <?php
/**
* Mouse Model
*/
namespace webserver\models\devTestEvent\testEvent;
use common\models\devTestEvent\testEvent\BaseModel; use webserver\exceptions\Exception; use webserver\event\devTestEvent\testEvent\CatEvent; use webserver\event\devTestEvent\testEvent\MouseEvent;
/**
* Class Mouse
*
* @property int $id
* @property int $type
* @property string $content
* @property int $createdAt
*
* @package webserver\models\devTestEvent\testEvent
*/
class Mouse extends BaseModel
{
/**
* event: 老鼠听到了猫叫, 跑了
*/
public const EVENT_MOUSE_RUN = 'run';
public function init()
{
parent::init();
$this->type = self::TYPE_MOUSE; //`type`默认为老鼠
}
/**
* 事件handler: 猫叫了之后,触发老鼠跑的事件处理器
* @param CatEvent $event
* @throws EzException
*/
public function run(CatEvent $event)
{
$model = new self();
$model->content = date('Y-m-d H:i:s') . "我是一只老鼠, 听到了猫(#{$event->catId})叫, 所以我逃跑了!";
$result = $model->save();
if (!$result) {
throw new Exception(Exception::ERROR_TRANSACTION_ERROR, '地上打滑,逃跑失败,被猫抓住了');
}
}
public function beforeSave($insert)
{
// 看到老鼠发出的动静(老鼠成功逃跑:插入一条数据成功后,说明老鼠成功逃跑了),于是人把鞋子扔了出去(插入一条数据)
$this->on(self::EVENT_MOUSE_RUN, [Person::class, 'do']);
return parent::beforeSave($insert);
}
public function afterSave($insert, $changedAttributes)
{
parent::afterSave($insert, $changedAttributes);
if ($insert) {
$mouseEvent = new MouseEvent();
$mouseEvent->mouseId = $this->id;
$this->trigger(self::EVENT_MOUSE_RUN, $mouseEvent);
}
}
}
Dog.php:
<?php
/**
* Dog Model
*/
namespace webserver\models\devTestEvent\testEvent;
use common\models\devTestEvent\testEvent\BaseModel; use webserver\exceptions\Exception; use webserver\event\devTestEvent\testEvent\CatEvent; use webserver\event\devTestEvent\testEvent\DogEvent;
/**
* Class Dog
*
* @property int $id
* @property int $type
* @property string $content
* @property int $createdAt
*
* @package webserver\models\devTestEvent\testEvent
*/
class Dog extends BaseModel
{
/**
* event: 狗听到猫叫,看了一眼
*/
public const EVENT_DOG_LOOK = 'look';
public function init()
{
parent::init();
$this->type = self::TYPE_DOG; // `type`默认为狗
}
/**
* 事件handler: 猫叫了之后,狗看的事件处理器
* @param CatEvent $event
* @throws EzException
*/
public function look(CatEvent $event)
{
$model = new self();
$model->content = date('Y-m-d H:i:s') . "我是一只狗, 听到猫(#{$event->catId})叫, 所以看了猫一眼";
$result = $model->save();
if (!$result) {
throw new Exception(Exception::ERROR_TRANSACTION_ERROR, '呃,没睡醒,看花了眼');
}
}
public function beforeSave($insert)
{
// 狗看(插入一条数据成功后,说明狗看猫成功了)到了猫以后,触发了猫跑(再次插入一条数据)这个动作
$this->on(self::EVENT_DOG_LOOK, [Cat::class, 'run']);
return parent::beforeSave($insert);
}
public function afterSave($insert, $changedAttributes)
{
parent::afterSave($insert, $changedAttributes);
if ($insert) {
$dogEvent = new DogEvent();
$dogEvent->dogId = $this->id;
$this->trigger(self::EVENT_DOG_LOOK, $dogEvent);
}
}
}
Person.php:
<?php
/**
* Person Model
*/
namespace webserver\models\devTestEvent\testEvent;
use common\models\devTestEvent\testEvent\BaseModel; use ezsoft\exceptions\EzException; use webserver\event\devTestEvent\testEvent\MouseEvent;
/**
* Class Person
*
* @property int $id
* @property int $type
* @property string $content
* @property int $createdAt
*
* @package webserver\models\devTestEvent\testEvent
*/
class Person extends BaseModel
{
public function init()
{
parent::init();
$this->type = self::TYPE_PERSON;
}
/**
* 事件handler: 老鼠跑发出的动作热看到后的事件处理器
* @param MouseEvent $event
* @throws EzException
*/
public function do(MouseEvent $event)
{
$model = new self();
$model->content = date('Y-m-d H:i:s') . "我是这屋子的主人, 看到有一只老鼠(#{$event->mouseId})在跑,我把鞋子扔了出去";
$result = $model->save();
if (!$result) {
throw new EzException(EzException::ERROR_TRANSACTION_ERROR, '鞋子没扔出去, 上面有胶水,粘在手上了');
}
}
} ` ///////////////////////////////////////////////// 3.XxxEvent部分:该部分会在trigger事件时使用 ////////////////////////////////////////////////
CatEvent.php:
` <?php
/**
* 该Event 封装了与事件相关的有关数据,并提供一些功能函数作为辅助.
*/
namespace webserver\event\devTestEvent\testEvent;
use yii\base\Event;
/**
* Class CatEvent
* @package webserver\event\devTestEvent\testEvent
*/
class CatEvent extends Event
{
/**
* @var int 猫id
*/
public $catId;
} ` DogEvent.php:
` <?php
/**
* 该Event 封装了与事件相关的有关数据,并提供一些功能函数作为辅助.
*/
namespace webserver\event\devTestEvent\testEvent;
use yii\base\Event;
/**
* Class DogEvent
* @package webserver\event\devTestEvent\testEvent
*/
class DogEvent extends Event
{
/**
* @var int 狗id
*/
public $dogId;
} `
MouseEvent.php:
` <?php
/**
* 该Event 封装了与事件相关的有关数据,并提供一些功能函数作为辅助.
*/
namespace webserver\event\devTestEvent\testEvent;
use yii\base\Event;
/**
* Class MouseEvent
* @package webserver\event\devTestEvent\testEvent
*/
class MouseEvent extends Event
{
/**
* @var int 老鼠id
*/
public $mouseId;
} `
zhoupenghui
最后登录:2020-08-20
在线时长:44小时43分
- 粉丝3
- 金钱870
- 威望120
- 积分2510