当前位置:首页 > PHP > 正文内容

laravel的Observer观察者模式模型事件实战

陈杰2个月前 (12-31)PHP318

laravel的orm特别好用,特别是observer观察者模式,可以在不更改原有业务代码的情况下做到切入编程,有点类似于我们之前常用的钩子函数。


下面就是我们深入observer观察者模式的实战代码


现有一个业务逻辑是,我们的会员系统有一个经验值,当某个经验值达到某个临界点的时候我们就给这个会员升级权限。

但是获取这个经验值的渠道有很多,意思就是我们的获取经验值的代码可能存在多个地方,如果要去改动代码的话需要找到每个代码文件一一的更改代码。

有没有一种在不改动之前的业务代码下的只需要增加一个判断就能做到经验值达到>升级这步操作呢?


当然有,就是laravel的observer观察者模式。


看看实战代码

<?php
namespace App\Observers\Member;
use App\Model\Member\MemberModel;

class MemberObserver
{
    public function saving(MemberModel $model)
    {
        //如果面经值大于1000 或者mvp大于10   并且是普通会员
        if (($model->exp_interview >= 1000 || $model->exp_mvp >= 10) and $model->role_interview == 0) {
            $model->role_interview = 1;
        }
        if (isset($model['exp_interview']) and isset($model['exp_shen'])) {
            $model['exp_interview'] = $model['exp_interview'] >= 0 ? $model['exp_interview'] : 0;
            $model['exp_shen']      = $model['exp_shen'] >= 0 ? $model['exp_shen'] : 0;
        }
        return $model;
    }

    public function created(MemberModel $model)
    {
        //新用户注册
        if ($model->pid !== 0) {
            $member = MemberModel::query()->select('id', 'name')->find($model->pid);
            if (isset($member)) {
                $count             = MemberModel::query()->where('pid', $model->pid)->count();
                $member->sub_count = $count;
                $member->save();
            }
        }
    }
}

这里我们新建了一个MemberObserver类,主要就是我们的业务逻辑


方法saving就是当MemberModel 就是我们的会员表发生正在保存中的事件时,当经验值大于多少,就把我们的权限升级为某个等级。

方法created意思为当MemberModel模型发生insert插入成功后触发的事件,插入成功肯定就是我们的会员注册成功了,给邀请人发放奖励之类的逻辑就可以写在这里。


现在我们的观察者定义好了,就要让我们的观察者正常工作。


来到\app\Providers目录下找到AppServiceProvider.php文件

在boot方法中注册一下我们的MemberObserver

 public function boot()
    {
        MemberModel::observe(MemberObserver::class);
    }


至此我们的观察者就注册好了,这里的意思就是让MemberObserver去观察MemberModel模型


观察者中还可以定义其他的一些事件,这些都是laravel为我们定义好了的

retrieved

creating

created

updating

updated

saving

saved

deleting

deleted

restoring

restored


具体的事件类型可以去查询一下laravel的官方文档


再让我们看看为什么我们能监听到模型的事件,查看一下laravel的源代码


找到模型基类 \vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php


以save方法为例


/**
* Save the model to the database.
*
*
@param  array  $options
* @return bool
*/
public function save(array $options = [])
{
   
$query = $this->newModelQuery();

   
// If the "saving" event returns false we'll bail out of the save and return
   // false, indicating that the save failed. This provides a chance for any
   // listeners to cancel save operations if validations fail or whatever.
   
if ($this->fireModelEvent('saving') === false) {
       
return false;
   
}

   
// If the model already exists in the database we can just update our record
   // that is already in this database using the current IDs in this "where"
   // clause to only update this model. Otherwise, we'll just insert them.
   
if ($this->exists) {
       
$saved = $this->isDirty() ?
                   
$this->performUpdate($query) : true;
   
}

   
// If the model is brand new, we'll insert it into our database and set the
   // ID attribute on the model to the value of the newly inserted row's ID
   // which is typically an auto-increment value managed by the database.
   
else {
       
$saved = $this->performInsert($query);

       if
(! $this->getConnectionName() &&
           
$connection = $query->getConnection()) {
           
$this->setConnection($connection->getName());
       
}
   }

   
// If the model is successfully saved, we need to do a few more things once
   // that is done. We will call the "saved" method here to run any actions
   // we need to happen after a model gets successfully saved right here.
   
if ($saved) {
       
$this->finishSave($options);
   
}

   
return $saved;
}


在save方法中我们看到有一个

    if ($this->fireModelEvent('saving') === false) {
       
return false;
   
}

这里就是去触发我们的saving方法,


不得不感叹laravel的orm真的是非常的好用,确实加入了很多现代编程的规范和一些奇思妙想的方法。。

扫描二维码至手机访问

扫描二维码推送至手机访问。

版权声明:本文由何烦过虎溪发布,如需转载请注明出处。

转载请注明出处:http://95shouyou.com/?id=27

分享给朋友:

相关文章

Laravel带条件查询多个count

Laravel带条件查询多个count

在一个数据表中,我们需要用到聚合函数count来查询符合条件的总数。举例一个场景:我们有一个帖子,这个帖子可以分别被好中差评,好中差评记录用一个单独的记录表来存储。如果用户点击好评,那么该帖子作者的经...

laravel跨库多态关联实战

laravel跨库多态关联实战

点赞记录表做了分库分表,位于副库里面表结构该点赞表关联了8个不同的表,因为业务原因,评论回复表有四个板块,所以做了4个评论记录表,4个回复记录表,且结构有细微不同。目标是用户获得被点赞记录,根据不同的...

七牛云删除文件和批量删除文件

在项目中因为用到了七牛云的对象存储,价格公道,也降低我们的项目维护成本。但是在实际使用过程中,例如用户换了头像我们就需要删除用户之前的头像,以降低我们的存储成本。所以研究了一下七牛云的删除单个文件和批...

laravel集成极光推送实战

公司项目需要用到app推送消息通知,市面上很多推送渠道商,选来选去最终选定了极光推送,因为项目使用laravel写的,laravel自身又有模型事件,所以研究了一下,在不改动原有代码的情况下,给项目加...

php对接支付宝转账到第三方接口实战

公司项目有一个用户钱包系统,用户创作的内容可以收到游客的打赏,当然就需要提现的接口了。最终选定的是支付宝转账接口,公司代收账户直接打款给用户绑定的支付宝账号,再也不用人工手动打款了。上代码准备好工具,...

利用workerman实现webrtc实时音视频通话

利用workerman实现webrtc实时音视频通话

实现原理利用workerman的websocket实现实时消息传递。webrtc自带p2p功能,利用STUN中继服务器实现webrtc实时音视频看看我们的前端文件,只是一个单页面<html>...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。