保存之前的事件示例
public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
// 插入新数据判断订单号是否存在
if (!Order::findModel(['trade_no' => $this->order_trade_no])) {
throw new Exception("订单号不存在");
}
return true;
} else {
return false;
}
}
保存之后的事件示例
public function afterSave($insert, $changedAttributes)
{
parent::afterSave($insert, $changedAttributes);
if ($insert) {
// 插入新数据之后修改订单状态
Order::updateAll(['shipping_status' => Order::SHIPPING_STATUS1, 'shipping_at' => time()], ['trade_no' => $this->order_trade_no]);
}
}
删除之后的事件示例
public function afterDelete()
{
parent::afterDelete();
}
Model 事件怎么保证数据事务呢?
添加一下代码在 Model 中:
public function transactions()
{
return [
self::SCENARIO_DEFAULT => self::OP_INSERT | self::OP_UPDATE | self::OP_DELETE
// self::SCENARIO_DEFAULT => self::OP_INSERT
];
}
每次请求之前操作示例
/**
* @param \yii\base\Action $action
* @return bool
* @throws \yii\web\BadRequestHttpException
*/
public function beforeAction($action)
{
if (parent::beforeAction($action)) {
$this->request = Yii::$app->request;
Yii::info($this->request->absoluteUrl, '请求地址');
Yii::info($this->request->rawBody, '请求数据');
return true;
} else {
return false;
}
}
每次请求之后操作示例
/**
* @param \yii\base\Action $action
* @param mixed $result
* @return array|mixed
* @throws BusinessException
*/
public function afterAction($action, $result)
{
Yii::info(\yii\helpers\Json::encode($result), '请求返回结果');
return $result;
}
删除之前的操作
public function beforeDelete()
{
if (Business::find()->where(['louma_id' => $this->id])->count('id')) {
Yii::$app->session->setFlash('error', '请先删除此楼宇的商户');
return false;
}
return parent::beforeDelete();
}
待续……
本文由 forecho 创作,采用 知识共享署名 3.0 中国大陆许可协议 进行许可。 可自由转载、引用,但需署名作者且注明文章出处。
如果这篇文章对您有帮助,不妨微信小额赞助我一下,让我有动力继续写出高质量的教程。
在楼主的神武文档下面,补充一下自己写一个event的方法步骤:
1.Yii2 使用Event -1 ,如何使用事件:
http://www.fancyecommerce.com/2016/04/29/yii2-使用event-1-,如何使用事件/
2.Yii2 使用Event -2 ,如何使用事件:
http://www.fancyecommerce.com/2016/04/29/yii2-使用event-2-,如何使用事件/
@zxx1988328 #2楼 已更新
这个应该是装饰器模式,作用是可以动态的添加和修改功能(其实只是看起来比较像装饰器模式,无视无视……)
事件的话,也就是观察者模式,触发一个事件后通知所有观察这个事件的观察者,观察者可以是多个。比如当保存一个 Model 的时候,触发 saving 事件,这个时候就可以编写一个保存日志和一个更新缓存的观察者,以后只要保存 Model ,就可以把日志记录下来,同时更新缓存
<?php
abstract class Model
{
private $event;
public function __construct(Event $event)
{
$this->event = $event;
}
public function save()
{
$this->event->notify('saving', $this);
}
}
class User extends Model
{
}
class Blog extends Model
{
}
class Event
{
private $events;
public function addObserver($name, IObserver $observer){
$this->events[$name][] = $observer;
}
public function notify($name, $model){
echo get_class($model) . PHP_EOL;
foreach ($this->events[$name] as $observer) {
$observer->doSomething($model);
}
}
}
interface IObserver{
public function doSomething(Model $model);
}
class LogObserver implements IObserver{
public function doSomething(Model $model){
echo 'Log...' . PHP_EOL;
}
}
class CacheObserver implements IObserver{
public function doSomething(Model $model){
echo 'Cache...' . PHP_EOL;
}
}
$event = new Event();
$event->addObserver('saving', new LogObserver());
$event->addObserver('saving', new CacheObserver());
$user = new User($event);
$user->save();
$blog = new Blog($event);
$blog->save();
执行结果:
User
Log...
Cache...
Blog
Log...
Cache...
@xjdata [#8楼](#comment8) 这是可以满足那段描述的一个实现。
别看那么长…… 其实就是 Model
里的 save()
方法触发 saving
事件,然后 Event
里依次通知(执行)注册(添加)好的观察者LogObserver
和 CacheObserver
。
我翻了下文档…… 发现楼主这个确实是 Yii 的事件的正确使用姿势…… 好尴尬啊…… 没看文档没看源码就直接回答了…… 只是看起来有点像装饰器模式…… 怎么办…… 好尴尬……
http://www.yiiframework.com/doc-2.0/yii-db-baseactiverecord.html#beforeSave()-detail
这里的 beforeSave
和 afterSave
其实就是触发的 EVENT_BEFORE_INSERT
和 EVENT_AFTER_INSERT
事件。
@xjdata [[#11楼](#comment11)](#comment11) yii2 的 ActiveRecord 已经提前预制好了 ⑨ 个事件,如下:
http://www.yiiframework.com/doc-2.0/yii-db-baseactiverecord.html#EVENT_AFTER_DELETE-detail
你只需要添加对应的处理就可以了:
http://www.getyii.com/doc-2.0/guide/concept-events.html#
看这个文档的 类级别的事件处理器
部分,那个例子应该就是你想要的了……
补充删除之前事件
public function beforeDelete()
{
if (parent::beforeDelete()) {
// something code
return true;
} else {
return false;
}
}
@fecommerce #16楼 为啥这么说?