简单的介绍 Eloquent 模型生命周期
@这是小豪的第七篇文章
在没有接触 Laravel 的时候,都还不知道 PHP 有事件、模型生命周期这一说,一直都是什么时候需要什么时候调用,代码写的一大坨,哈哈,今天带大家来看看 Eloquent 模型生命周期到底是什么样子的什么时候使用。
准备
我们以文章为例子:
class Post extends Model { protected $fillable = [ 'user_id', 'title', 'content', ]; protected $casts = [ 'id' => 'int', 'user_id' => 'int', ]; protected static function boot() { parent::boot(); // TODO: Change the autogenerated stub static::retrieved(function (Post $post) { echo 'This is retrieved' . "\n"; }); static::creating(function (Post $post) { echo 'This is creating' . "\n"; }); static::created(function (Post $post) { echo 'This is created' . "\n"; }); static::updating(function (Post $post) { echo 'This is updating' . "\n"; }); static::updated(function (Post $post) { echo 'This is updated' . "\n"; }); static::saving(function (Post $post) { echo 'This is saving' . "\n"; }); static::saved(function (Post $post) { echo 'This is saved' . "\n"; }); static::deleting(function (Post $post) { echo 'This is deleting' . "\n"; }); static::deleted(function (Post $post) { echo 'This is deleted' . "\n"; }); } } 创建文章
public function store(Request $request) { $post = Post::create(['title' => '这是文章标题', 'content' => '这是文章内容', 'user_id' => Auth::id()]); return \response()->json($post); } 此时我们可以看到输出的顺序依次为:
| 1 | 2 | 3 | 4 |
|---|---|---|---|
| This is saving | This is creating | This is created | This is saved |
更新文章
public function update(Request $request) { $post = Post::find(1); $post->title = '这是更新的文章标题'; $post->save(); return \response()->json($post); } 此时我们可以看到输出的顺序依次为:
| 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|
| This is retrieved | This is saving | This is updating | This is updated | This is saved |
从简单的更新与创建中,大家可以看到触发的事件中多了一个
retrieved,以及creating、created依次变为了updating、updated,其余的都是保持一致的。多出来的retrieved是从哪里蹦出来的呢,我们看看文档中给出的解释:“当从数据库检索现有模型时,会触发retrieved 事件”
其实我刚才看到这句话的时候有点蒙,啥呀,哈哈。下面简单给大家再演示一遍看看:
public function test() { $post = Post::find(1); // 输出:This is retrieved $post = Post::create(['title' => '这是文章标题 2 ', 'content' => '这是文章内容 2 ', 'user_id' => Auth::id()]); // 输出:..... $posts = Post::all(); // 输出:This is retrieved、This is retrieved } 大家有没有看出啥子端倪,哈哈,一条记录触发了一次。
删除文章
public function destroy(Request $request) { $post = Post::find(1); $post->delete(); } 此时我们可以看到输出的顺序依次为:
| 1 | 2 | 3 |
|---|---|---|
| This is retrieved | This is deleting | This is deleted |
批量更新
public function test(Request $request) { Post::where('id' ,'>' ,0)->update(['title' => '这是文章标题更新', 'content' => '这是文章内容', 'user_id' => 1]); } 此时我们可以看到没有输出,为啥呢?通过 Eloquent 进行批量更新时,不会为更新的模型触发 saved 和 updated 模型事件。这是因为在进行批量更新时,并未检索该模型。
批量删除
public function test(Request $request) { Post::where('id' ,'>' ,0)->delete(); } 也是一样没有输出的噢,哈哈。
结束语
大家可能会问啥时候会用到这些模型事件呢,举例一些给大家看看:
protected static function boot() { parent::boot(); // TODO: Change the autogenerated stub static::retrieved(function (Post $post) { // 文章加精 \dispatch(new PostAddPopular($post)); }); static::creating(function (Post $post) { $post->user_id = Auth::id(); }); static::saving(function (Post $post) { // 敏感词过滤 $post->title = \dispatch_now(new FilterThreadSensitiveWords($post->title)); }); } ...... 等等还有好多妙用,大家可以结合自己的需求对生命周期完美的利用哈哈。
也可以定义一个观察者进行监听处理的,不过没有很大处理量的时候,还是建议这种直接在模型中定义的方式噢。
本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
棒棒棒~~~~谢谢
有个问题,这种没法触发update事件
User::where('id',1)->update(['name'=>'test'])@lovecn 批量更新是不会触发事件的噢,哪怕只是
where('id', 1),User::find(1)->update(['name' => 'test']);这样才会触发事件噢。楼主能分享一下FilterThreadSensitiveWords的实现吗