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://www.95shouyou.com/?id=27
网友评论