Laravel 模型事件的应用
19

在日常处理一些用户操作事件时,我们有时候需要记录下来,方便以后查阅,或者大数据统计。


Laravel 在模型事件中处理起来很方便:https://laravel-china.org/docs/laravel/5.5/eloquent#events


Laravel 的模型事件有两种方式,

  • 设置dispatchesEvents属性映射事件类
  • 使用观察器来注册事件,这里介绍第二种

  • 新建模型
    php artisan make:model Log
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Log extends Model
{
    protected $fillable = ['user_name', 'user_id', 'url', 'event', 'method', 'table', 'description'];
}
  • 创建迁移表:
    php artisan make:migration create_logs_table
  • 表的结构大概是这样,可按需设计
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateLogsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('logs', function (Blueprint $table) {
            $table->engine = 'InnoDB';
            $table->increments('id');
            $table->string('user_id')->comment('操作人的ID');
            $table->string('user_name')->comment('操作人的名字,方便直接查阅');
            $table->string('url')->comment('当前操作的URL');
            $table->string('method')->comment('当前操作的请求方法');
            $table->string('event')->comment('当前操作的事件,create,update,delete');
            $table->string('table')->comment('操作的表');
            $table->string('description')->default('');
            $table->timestamps();
        });

        DB::statement("ALTER TABLE `logs` comment '操作日志表'");
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('logs');
    }
}
  • 运行迁移生成表
    php artisan migrate
  • 新建一个服务提供者统一注册所有的模型事件观察器(后面的名字可以自己起得形象一点)
    php artisan make:provider ObserverLogServiceProvider
  • /config/app.php中的providers数组注册(大概如图中)
  • app目录下新建文件夹Observers存放模型观察器,并新建基类LogBaseServer并在构造函数构建基本属性(CLI是因为在命令行执行时不存在用户执行)
  • 新建一个观察器继承基类LogBaseServerUser模型,方法的名字要对应文档中的事件)
  • 到新建的服务提供者ObserverLogServiceProvider中运行
  • 为需要的模型注册事件(我这挺多的,之后大概长这样)
  • 然后我们触发一些事件(增删改,表的数据就有了)

  • 多对多的关联插入不会出触发模型(比如attach方法)
  • 这时候就需要自己新建事件类来模拟(这里拿分配权限给角色粗略说一下)
    1. EventServiceProvider中的listen属性绑定好事件
    2. 事件PermissionRoleEvent中的注入两个参数,一个是角色,另一个是attach或者detach返回的数组
    3. 事件监听器PermissionRoleEventLog也继承基类LogBaseServer,这里就是根据传入的数组id遍历,然后创建日志
    4. 之后应用事件

  • 更优雅的处理登录注销事件
    1. EventServiceProvider中的subscribe属性绑定好处理的类
    2. 事件监听类的方法
    3. 之后的效果就是这样了:

      END

      原文地址

当神不再是我们的信仰,那么信仰自己吧,努力让自己变好,不辜负自己的信仰!

本帖由系统于 5个月前 自动加精
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 2
  • 可以封装基础Observer类
    
    <?php

use Illuminate\Contracts\Bus\Dispatcher as CommandDispatcher;
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
use Illuminate\Foundation\Bus\DispatchesJobs;

class Observer
{
use DispatchesJobs;

/**
 * The event dispatcher.
 *
 * @var EventDispatcher
 */
protected $events;

/**
 * The command dispatcher.
 *
 * @var CommandDispatcher
 */
protected $commands;

/**
 * Create a new EloquentObserver instance.
 *
 * @param EventDispatcher   $events
 * @param CommandDispatcher $commands
 */
public function __construct(EventDispatcher $events, CommandDispatcher $commands)
{
    $this->events   = $events;
    $this->commands = $commands;
}

}


* 模型

<?php

class PorductObserver extends Observer
{
public function saving(PorductModelInterface $product)
{

    $this->commands->dispatch(new SetMetaInformation($product));

    $this->events->fire(new PorductWasSaved($product));
}

}

3个月前

学习了

3个月前

  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!