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

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

陈杰4个月前 (12-31)PHP632

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

分享给朋友:

相关文章

Lumen框架报错Class session does not exist

Lumen框架报错Class session does not exist

由于lumen框架是为速度而生的 Laravel 框架,所以移除了session的支持,虽然在ide中代码提示可以敲出Session::put()方法出来,但是最终还是提示的是Class sessio...

laravel分表model映射的思路

预先估计会出现大数据量并且访问频繁的表,将其分为若干个表这种预估大差不差的,论坛里面发表帖子的表,时间长了这张表肯定很大,几十万,几百万都有可能。 聊天室里面信息表,几十个人在一起一聊一个晚上,时间长...

laravel通过模板html生成word文档

laravel通过模板html生成word文档

因为公司项目需要,内部的管理系统有一个php实时查询数据库,根据内容来生成word文档排版没有什么需求,实现原理是查询数据库,然后用laravel自带的模板引擎,生成一个html网页,然后修改网页的r...

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

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

通过代码创建多个同样的mysql表

在分库分表中可能要同时创建多个结构相同但后缀不同的表,通过代码实现for ($i = 3; $i <= 20; $i++) {    DB::connection('...

laravel实现微信公众号授权登录实战

微信公众号授权登录实战框架:laravel依赖:overtrue/wechat首先安装一下easywechat依赖composer require overtrue/wechat:...

发表评论

访客

看不清,换一张

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