Laravel 5.3 --緩存

1讼呢、配置

Laravel 為不同的緩存系統(tǒng)提供了統(tǒng)一的 API。緩存配置位于 config/cache.php谦炬。在該文件中你可以指定在應(yīng)用中默認(rèn)使用哪個緩存驅(qū)動悦屏。Laravel 目前支持主流的緩存后端如 MemcachedRedis 等。
緩存配置文件還包含其他文檔化的選項键思,確保仔細(xì)閱讀這些選項础爬。默認(rèn)情況下,Laravel 被配置成使用文件緩存吼鳞,這會將序列化數(shù)據(jù)和緩存對象存儲到文件系統(tǒng)看蚜。對大型應(yīng)用,建議使用內(nèi)存緩存如 Memcached 或 APC赔桌,你甚至可以為同一驅(qū)動配置多個緩存配置供炎。

驅(qū)動預(yù)備知識

數(shù)據(jù)庫使用 database緩存驅(qū)動時,你需要設(shè)置一張表包含緩存緩存項疾党。下面是該表的 Schema 聲明:

Schema::create('cache', function($table) { 
    $table->string('key')->unique(); 
    $table->text('value'); $table->integer('expiration');}
);

注:你還可以使用Artisan命令php artisan cache:table
通過相應(yīng)的schema生成遷移音诫。

Memcached
使用 Memcached 緩存要求安裝了Memcached PECL 包,即 PHP Memcached 擴展雪位。你可以在配置文件config/cache.php中列出所有Memcached服務(wù)器:

'memcached' => [ [ 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 100 ],],

你還可以設(shè)置 host選項為 UNIX socket 路徑纽竣,如果你這樣做,port選項應(yīng)該置為 0:

'memcached' => [ 
    [ 'host' => '/var/run/memcached/memcached.sock', 
      'port' => 0, 
      'weight' => 100 
    ],
],

Redis
使用 Laravel 的 Redis 緩存之前茧泪,你需要通過 Composer 安裝 predis/predis
包(~1.0)。
想要了解更多關(guān)于 Redis 的配置聋袋,查看Redis文檔队伟。

2、緩存使用

獲取緩存實例

Illuminate\Contracts\Cache\FactoryIlluminate\Contracts\Cache\Repository 契約提供了訪問 Laravel 的緩存服務(wù)的方法幽勒。Factory 契約提供了所有訪問應(yīng)用定義的緩存驅(qū)動的方法嗜侮。Repository 契約通常是應(yīng)用中cache配置文件中指定的默認(rèn)緩存驅(qū)動的一個實現(xiàn)。
不過,你還可以使用 Cache 門面锈颗,這也是我們在整個文檔中使用的方式顷霹,Cache門面提供了簡單方便的方式對底層 Laravel 緩存契約實現(xiàn)進行訪問。
例如击吱,讓我們在控制器中導(dǎo)入 Cache門面:

<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Cache;
class UserController extends Controller{
/** 
* Show a list of all users of the application. 
* 
* @return Response 
*/
     public function index() { 
           $value = Cache::get('key'); // 
     }
}

訪問多個緩存存儲
使用 Cache 門面淋淀,你可以使用 store方法訪問不同的緩存存儲器,傳入store方法的鍵就是 cache 配置文件中stores 配置數(shù)組里列出的相應(yīng)的存儲器:

$value = Cache::store('file')->get('foo');
Cache::store('redis')->put('bar', 'baz', 10);

從緩存中獲取數(shù)據(jù)
Cache門面的 get方法用于從緩存中獲取緩存項覆醇,如果緩存項不存在朵纷,返回 null。如果需要的話你可以傳遞第二個參數(shù)到 get方法指定緩存項不存在時返回的自定義默認(rèn)值:

$value = Cache::get('key');
$value = Cache::get('key', 'default');

你甚至可以傳遞一個閉包作為默認(rèn)值永脓,如果緩存項不存在的話閉包的結(jié)果將會被返回袍辞。傳遞閉包允許你可以從數(shù)據(jù)庫或其它外部服務(wù)獲取默認(rèn)值:

$value = Cache::get('key', function() 
{ 
    return DB::table(...)->get();
});

檢查緩存項是否存在
has方法用于判斷緩存項是否存在:

if (Cache::has('key')) { //}

數(shù)值增加/減少
incrementdecrement方法可用于調(diào)整緩存中的整型數(shù)值。這兩個方法都可以接收第二個參數(shù)來指明緩存項數(shù)值增加和減少的數(shù)目:

Cache::increment('key');
Cache::increment('key',$amount);
Cache::decrement('key');
Cache::decrement('key', $amount);

獲取&存儲
有時候你可能想要獲取緩存項常摧,但如果請求的緩存項不存在時給它存儲一個默認(rèn)值搅吁。例如,你可能想要從緩存中獲取所有用戶落午,或者如果它們不存在的話谎懦,從數(shù)據(jù)庫獲取它們并將其添加到緩存中,你可以通過使用 Cache::remember方法實現(xiàn):

$value = Cache::remember('users', $minutes, function() 
{
    return DB::table('users')->get();
});

如果緩存項不存在板甘,傳遞給remember 方法的閉包被執(zhí)行并且將結(jié)果存放到緩存中党瓮。
你還可以聯(lián)合 rememberforever方法:

$value = Cache::rememberForever('users', function() 
{ 
    return DB::table('users')->get();
});

獲取&刪除
如果你需要從緩存中獲取緩存項然后刪除,你可以使用pull 方法盐类,和 get方法一樣寞奸,如果緩存項不存在的話返回null:

$value = Cache::pull('key');

在緩存中存儲數(shù)據(jù)
你可以使用 Cache門面上的 put 方法在緩存中存儲數(shù)據(jù)。當(dāng)你在緩存中存儲數(shù)據(jù)的時候在跳,需要指定數(shù)據(jù)被緩存的時間(分鐘數(shù)):

Cache::put('key', 'value', $minutes);

除了傳遞緩存項失效時間枪萄,你還可以傳遞一個代表緩存項有效時間PHP Datetime實例:

$expiresAt = Carbon::now()->addMinutes(10);
Cache::put('key', 'value', $expiresAt);

緩存不存在的情況下存儲數(shù)據(jù)
add方法只會在緩存項不存在的情況下添加數(shù)據(jù)到緩存,如果數(shù)據(jù)被成功添加到緩存返回 true猫妙,否則瓷翻,返回false

Cache::add('key', 'value', $minutes);

永久存儲數(shù)據(jù)
forever方法用于持久化存儲數(shù)據(jù)到緩存,這些值必須通過 forget方法手動從緩存中移除:

Cache::forever('key', 'value');

注:如果你使用的是Memcached驅(qū)動割坠,當(dāng)緩存數(shù)據(jù)達到上限后永久存儲的數(shù)據(jù)就會被移除齐帚。

從緩存中移除數(shù)據(jù)
你可以使用 Cache門面上的 forget方法從緩存中移除緩存項數(shù)據(jù):

Cache::forget('key');

還可以使用 flush方法清除所有緩存:

Cache::flush();

注:清除緩存并不管什么緩存鍵前綴,而是從緩存系統(tǒng)中移除所有數(shù)據(jù)彼哼,所以在使用這個方法時如果其他應(yīng)用與本應(yīng)用有共享緩存時需要格外注意对妄。

3、緩存標(biāo)簽

注:緩存標(biāo)簽?zāi)壳安恢С?file或 database 緩存驅(qū)動敢朱,此外剪菱,當(dāng)使用多標(biāo)簽的緩存被設(shè)置為永久存儲時摩瞎,使用memcached 驅(qū)動的緩存有著最佳性能表現(xiàn),因為 Memcached 會自動清除陳舊記錄孝常。

存儲被打上標(biāo)簽的緩存項
緩存標(biāo)簽允許你給相關(guān)緩存項打上同一個標(biāo)簽以便于后續(xù)清除這些緩存值旗们,被打上標(biāo)簽的緩存可以通過傳遞一個被排序的標(biāo)簽數(shù)組來訪問。例如构灸,我們可以通過以下方式在添加緩存的時候設(shè)置標(biāo)簽:

Cache::tags(['people', 'artists'])->put('John', $john, $minutes);
Cache::tags(['people', 'authors'])->put('Anne', $anne, $minutes);

你可以給多個緩存項打上相同標(biāo)簽上渴,這是沒有數(shù)目限制的。
訪問被打上標(biāo)簽的緩存項
要獲取被打上標(biāo)簽的緩存項冻押,傳遞同樣的有序標(biāo)簽數(shù)組到 tags
方法然后使用你想要獲取的key來調(diào)用get 方法:

$john = Cache::tags(['people', 'artists'])->get('John');
$anne = Cache::tags(['people', 'authors'])->get('Anne');

移除被打上標(biāo)簽的數(shù)據(jù)項
你可以同時清除被打上同一標(biāo)簽/標(biāo)簽列表的所有緩存項驰贷,例如,以下語句會移除被打上 peopleauthors標(biāo)簽的所有緩存:

Cache::tags(['people', 'authors'])->flush();

這樣洛巢,上面設(shè)置的 Anne 和 John 緩存項都會從緩存中移除括袒。
相反,以下語句只移除被打上 authors 標(biāo)簽的語句稿茉,所以只有 Anne 會被移除而 John 不會:

Cache::tags('authors')->flush();

4锹锰、添加自定義緩存驅(qū)動
編寫驅(qū)動
要創(chuàng)建自定義的緩存驅(qū)動,首先需要實現(xiàn) Illuminate\Contracts\Cache\Store
契約漓库,所以恃慧,我們的 MongoDB緩存實現(xiàn)看起來會像這樣子:

<?php
namespace App\Extensions;
use Illuminate\Contracts\Cache\Store;
class MongoStore implements Store{
    public function get($key) {} 
    public function many(array $keys); 
    public function put($key, $value, $minutes) {} 
    public function putMany(array $values, $minutes); 
    public function increment($key, $value = 1) {} 
    public function decrement($key, $value = 1) {} 
    public function forever($key, $value) {} 
    public function forget($key) {} 
    public function flush() {} 
    public function getPrefix() {}
}

我們只需要使用一個 MongoDB 連接來實現(xiàn)其中的每一個方法,想要看如何實現(xiàn)每個方法的示例渺蒿,可以參考Laravel底層源碼Illuminate\Cache\MemcachedStore痢士,實現(xiàn)完成后,我們就可以完成自定義驅(qū)動注冊:

Cache::extend('mongo', function($app) 
{ 
    return Cache::repository(new MongoStore);
});

注:如果你在擔(dān)心將自定義緩存驅(qū)動代碼放到哪茂装,考慮將其放到Packgist怠蹂!或者,你可以在 app目錄下創(chuàng)建一個Extensions命名空間少态。然而城侧,記住 Laravel 并沒有一個嚴(yán)格的應(yīng)用目錄結(jié)構(gòu),你可以基于你的需要自由的組織目錄結(jié)構(gòu)彼妻。

注冊驅(qū)動
要通過Laravel注冊自定義的緩存驅(qū)動嫌佑,可以使用Cache門面上的extend方法。對Cache::extend的調(diào)用可以在Laravel自帶的App\Providers\AppServiceProvider提供的boot方法中完成侨歉,或者屋摇,你也可以創(chuàng)建自己的服務(wù)提供者來收容擴展——只是別忘了在配置文件config/app.php中注冊服務(wù)提供者到providers數(shù)組:

<?php
namespace App\Providers;
use App\Extensions\MongoStore;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\ServiceProvider;

class CacheServiceProvider extends ServiceProvider{ 
/** 
* Perform post-registration booting of services. 
* 
* @return void 
*/ 
    public function boot() { 
        Cache::extend('mongo', function($app) { 
            return Cache::repository(new MongoStore); 
        }); 
    } 
/** 
* Register bindings in the container. * 
* @return void 
*/
     public function register() 
    { 
      // 
    }
}

傳遞給 extend方法的第一個參數(shù)是驅(qū)動名稱。該值對應(yīng)配置文件 config/cache.php中的 driver選項幽邓。第二個參數(shù)是返回Illuminate\Cache\Repository實例的閉包摊册。該閉包中被傳入一個 $app實例,也就是服務(wù)容器的一個實例颊艳。
擴展被注冊后茅特,只需簡單更新配置文件config/cache.php的driver選項為自定義擴展名稱即可。

5棋枕、緩存事件

要在每次緩存操作時執(zhí)行代碼白修,你可以監(jiān)聽緩存觸發(fā)的事件,通常重斑,你可以將這些緩存處理器代碼放到EventServiceProvider中:

/** 
* The event listener mappings for the application. 
* 
* @var array
*/
protected $listen = [ 
'Illuminate\Cache\Events\CacheHit' => [ 'App\Listeners\LogCacheHit', ],
'Illuminate\Cache\Events\CacheMissed' => [ 'App\Listeners\LogCacheMissed', ], 
'Illuminate\Cache\Events\KeyForgotten' => [ 'App\Listeners\LogKeyForgotten', ], 
'Illuminate\Cache\Events\KeyWritten' => [ 'App\Listeners\LogKeyWritten', ],
];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末兵睛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子窥浪,更是在濱河造成了極大的恐慌祖很,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漾脂,死亡現(xiàn)場離奇詭異假颇,居然都是意外死亡,警方通過查閱死者的電腦和手機骨稿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門笨鸡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人坦冠,你說我怎么就攤上這事形耗。” “怎么了辙浑?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵激涤,是天一觀的道長。 經(jīng)常有香客問我判呕,道長倦踢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任佛玄,我火速辦了婚禮硼一,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘梦抢。我一直安慰自己般贼,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布奥吩。 她就那樣靜靜地躺著哼蛆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪霞赫。 梳的紋絲不亂的頭發(fā)上腮介,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機與錄音端衰,去河邊找鬼叠洗。 笑死甘改,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的灭抑。 我是一名探鬼主播十艾,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼腾节!你這毒婦竟也來了忘嫉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤案腺,失蹤者是張志新(化名)和其女友劉穎庆冕,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體劈榨,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡访递,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鞋既。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片力九。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖邑闺,靈堂內(nèi)的尸體忽然破棺而出跌前,到底是詐尸還是另有隱情,我是刑警寧澤陡舅,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布抵乓,位于F島的核電站,受9級特大地震影響靶衍,放射性物質(zhì)發(fā)生泄漏灾炭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一颅眶、第九天 我趴在偏房一處隱蔽的房頂上張望蜈出。 院中可真熱鬧,春花似錦涛酗、人聲如沸铡原。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽燕刻。三九已至,卻和暖如春剖笙,著一層夾襖步出監(jiān)牢的瞬間卵洗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工弥咪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留过蹂,地道東北人十绑。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像榴啸,于是被迫代替她去往敵國和親孽惰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容