@這是小豪的第七篇文章
在沒有接觸 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 協議》,轉載必須註明作者和本文連結