您现在的位置是:网站首页 > 心得笔记

laravel中使用模型观察器

盛悦2019-01-11598人围观
简介如果要给某个模型监听很多事件,则可以使用观察器将所有监听器分组到一个类中。例如:我项目前台数据平日都是在缓存中获取的,但当我后台新增或修改帖子后,我想自动的删除缓存中帖子数据,这时候就可以使用模型观察器实现

如果要给某个模型监听很多事件,则可以使用观察器将所有监听器分组到一个类中。例如:我项目前台数据平日都是在缓存中获取的,但当我后台新增或修改帖子后,我想自动的删除缓存中帖子数据,这时候就可以使用模型观察器实现


在学习模型观察器之前,你需要了解以下几个小知识点:


1、Eloquent 模型会触发许多事件(Event),我们可以对模型的生命周期内多个时间点进行监控:creating, created, updating, updated, saving, saved, deleting, deleted, restoring, restored。


在 Eloquent 模型类上进行查询、插入、更新、删除操作时,会触发相应的模型事件,不管你有没有监听它们。这些事件包括:

  1. retrieved —— 获取到模型实例后触发

  2. creating —— 插入到数据库前触发

  3. created —— 插入到数据库后触发

  4. updating —— 更新到数据库前触发

  5. updated —— 更新到数据库后触发

  6. saving —— 保存到数据库前触发(无论插入还是更新都会触发)

  7. saved —— 保存到数据库后触发(无论插入还是更新都会触发)

  8. deleting —— 从数据库删除记录前触发

  9. deleted —— 从数据库删除记录前触发

  10. restoring —— 恢复软删除记录前触发

  11. restored —— 恢复软删除记录后触发


事件能在每次在数据库中保存或更新特定模型类时轻松地执行代码。从数据库中检索现有模型时会触发 retrieved 事件。当新模型第一次被保存时, creating 以及 created 事件会被触发。如果模型已经存在于数据库中并且调用了 save 方法,会触发 updatingupdated 事件。在这两种情况下,saving / saved 事件都会触发。


  但是注意: 通过 Eloquent 进行批量更新时,不会为更新的模型触发 saved 和 updated 模型事件。这是因为在进行批量更新时,并未检索该模型!!!


2、要会使用模型操作数据库


具体教程,请参考laravel官网!!!我在这里简单说下我常用的模型操作数据库的实例:


2.1、save()新增数据

要在数据库中创建新记录,只需创建一个新的模型实例,并在模型上设置属性,然后调用 save 方法:

<?php

namespace App\Http\Controllers;

use App\Post;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    public function store(CreateRequest $createRequest,Post $post)
    {
      //方法一:直接在模型上设置属性
        $post->name = $createRequest->name;
        $post->save();
      
      //方法二:通过辅助函数fill(array)直接save()保存  使用fill()插入数据时一定要注意模型中$fillable的定义,只有在$fillable中定义的才能插入库里!!!
      $post->fill($createRequest->all())->save();
      
    }
}


2.2、save()修改数据

save 方法也可以用来更新数据库中已经存在的模型。要更新模型,则须先检索模型,再设置要更新的属性,然后再调用 save 方法。

 <?php

namespace App\Http\Controllers;

use App\Post;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    public function update(CreateRequest $createRequest)
    {
      //方法一:直接在模型上设置属性
          $data = $createRequest->all();
          $post = Post::find($data['id']);//必须先检索模型
        $post->update_time = date('Y-m-d H:i:s');//器这里没有使用系统的updated_at,需要手动设置它的值
        $post->save();
      
      //方法二:通过辅助函数fill(array)直接save()保存
      $data = $createRequest->all();
          $post = Post::find($data['id']);//必须先检索模型
        $data['update_time'] = date('Y-m-d H:i:s');//器这里没有使用系统的updated_at,需要手动设置它的值
        $post->fill($data)->save();
      
    }
}


上面是通过find()检索数据,也可直接将模型注入进来实现检索,这样减少了不必要的代码:

<?php

namespace App\Http\Controllers;

use App\Post;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    public function update(CreateRequest $createRequest,Post $post)
    {
      //方法一:直接在模型上设置属性
          $data = $createRequest->all();
          $post->update_time = date('Y-m-d H:i:s');//器这里没有使用系统的updated_at,需要手动设置它的值
          $post->save();
      
      //方法二:通过辅助函数fill(array)直接save()保存
        $data = $createRequest->all();
        $data['update_time'] = date('Y-m-d H:i:s');//器这里没有使用系统的updated_at,需要手动设置它的值
        $post->fill($data)->save();
      
    }
}





好了,了解了以上两个知识点后,可以开始学习模型观察器了!!!下面我就具体讲述我项目中使用观察器的实例:


步骤一:注册观察器

    要注册一个观察器,需要使用模型上的observe 方法。你可以在服务提供器中的 boot 方法注册观察器。在我的项目中,我便是在 AppServiceProvider 注册观察器:

<?php

namespace App\Providers;

use App\User;
use App\Observers\UserObserver;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 运行所有应用.
     *
     * @return void
     */
    public function boot()
    {
        User::observe(PostObserver::class);
    }

    /**
     * 注册服务提供.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}


步骤二:定义观察器

     Laravel 没有为观察器设置默认的目录,所以你可以创建任何你喜欢你的目录来存放,这里我直接在App下新建Observers目录:

<?php
namespace App\Observers;
use App\Model\Post;
use Illuminate\Support\Facades\Cache;

class PostObserver
{
    /**
     * @功能:监听帖子创建、更新事件
     * @description 因为我用的新增、更新、软删除都是使用的save()所以我这里只定义一个监听方法
     * @author Sheng Yue
     * @time 2019/01/09
     */
    public function saved (Post $post) {
        Cache::forget($post->cache_key);
    }
    

}

 注意:

    1、观察器类里的方法名应该对应 Eloquent 中你想监听的事件。
    2、每种方法接收 model 作为其唯一的参数。


至此,模型观察器的讲解就结束了,如果你学会了使用模型观察器,那么你一定会想我上面的新增、修改数据代码写的还是很不好,我就吧上面例子稍做修改:

<?php

namespace App\Http\Controllers;

use App\Post;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    public function update(CreateRequest $createRequest,Post $post)
    {
          $post->fill($createRequest->all())->save();
    }
}

  
这个时候模型观察器就要改为:

<?php
namespace App\Observers;
use App\Model\Post;
use Illuminate\Support\Facades\Cache;

class PostObserver
{
    /**
     * @功能:在帖子新增之前将新增时间手动添加进模型对象里
     * @description 因为我用的新增、更新、软删除都是使用的save()所以我这里只定义一个监听方法
     * @author Sheng Yue
     * @time 2019/01/09
     */
     
     public function saving (Post $post) {
         $post->create_time = date('Y-m-d H:i:s');
     }
     
     /**
     * @功能:监听帖子创建、更新事件
     * @description 因为我用的新增、更新、软删除都是使用的save()所以我这里只定义一个监听方法
     * @author Sheng Yue
     * @time 2019/01/09
     */
     
     
    public function saved (Post $post) {
        Cache::forget($post->cache_key);
    }
    

}


模型观察器的常用场景:

1、使用模型监控器实现计数器(阅读量、回复量、点击量) —— reply_count;
2、使用模型监控器的 deleted 方法做连带删除;(删除帖子的同时删除旗下所有回复)