Laravel 內置 Cache::remember() 便捷,但無法緩存 with() 預加載關聯等複雜查詢結果。本文展示如何通過 Cache::macro() 定義 want() 方法,實現統一的「緩存命中即返回,未命中執行閉包並存儲」模式。
// 基礎用法
if (!$article = Cache::get('article_1')) {
$article = Article::find(1);
Cache::forever('article_1', $article);
}
// 模型 rememberForever 但無法緩存關聯
$article = Article::rememberForever('article_1')->where('id', 1); // with() 失效
在 App\Providers\AppServiceProvider::boot() 或 bootstrap/app.php 中註冊:
Cache::macro('want', function ($key, $minutes = 0, $callback) {
if (! $data = Cache::get($key)) {
$data = call_user_func($callback);
if ($minutes == 0) {
Cache::forever($key, $data);
} else {
Cache::put($key, $data, $minutes);
}
}
return $data;
});
$id = Input::get('id');
$article = Cache::want("article_{$id}", 0, function () use ($id) {
return Article::with('tags')
->findOrFail($id, ['id', 'cid', 'title', 'content_html as content', 'created_at', 'updated_at']);
});
優勢:
sha1(serialize([$query->toSql(), $query->getBindings()])) 實現查詢級自動鍵。Cache::tags() 實現關聯緩存批量失效。Cache::add('lock:' . $key, true, 10) 防止緩存擊穿。此宏模式已在多個高併發項目驗證,極大減少樣板代碼,提升可維護性。