Laravel為不同的緩存系統(tǒng)提供了統(tǒng)一的API。緩存配置位于config/cache.php
。在該文件中你可以指定在應用中默認使用哪個緩存驅(qū)動。Laravel目前支持流行的緩存后端如Memcached和Redis等。
緩存配置文件還包含其他文檔化的選項,確保仔細閱讀這些選項。默認情況下,Laravel被配置成使用文件緩存,這會將序列化數(shù)據(jù)和緩存對象存儲到文件系統(tǒng)。對大型應用,建議使用內(nèi)存緩存如Memcached或APC,你甚至可以為同一驅(qū)動配置多個緩存配置。
使用database
緩存驅(qū)動時,你需要設置一張表包含緩存緩存項。下面是該表的Schema
聲明:
Schema::create('cache', function($table) {
$table->string('key')->unique();
$table->text('value');
$table->integer('expiration');
});
使用Memcached緩存要求安裝了Memcached PECL 包,即PHP Memcached擴展。
Memcached::addServer默認配置使用TCP/IP協(xié)議:
'memcached' => [
[
'host' => '127.0.0.1',
'port' => 11211,
'weight' => 100
],
],
你還可以設置host
?選項為UNIX socket路徑,如果你這樣做,port
選項應該置為0:
'memcached' => [
[
'host' => '/var/run/memcached/memcached.sock',
'port' => 0,
'weight' => 100
],
],
使用Laravel的Redis緩存之前,你需要通過Composer安裝predis/predis
包(~1.0)。
了解更多關于Redis的配置,查看Larave的Redis文檔。
Illuminate\Contracts\Cache\Factory
和Illuminate\Contracts\Cache\Repository
契約提供了訪問Laravel的緩存服務的方法。Factory
契約提供了所有訪問應用定義的緩存驅(qū)動的方法。Repository
契約通常是應用中cache
配置文件中指定的默認緩存驅(qū)動的一個實現(xiàn)。
然而,你還可以使用Cache
門面,這也是我們在整個文檔中使用的方式,Cache
門面提供了簡單方便的方式對底層Laravel緩存契約實現(xiàn)進行訪問。
例如,讓我們在控制器中導入Cache
門面:
<?php
namespace App\Http\Controllers;
use Cache;
use Illuminate\Routing\Controller;
class UserController extends Controller{
/**
* 顯示應用所有用戶列表
*
* @return Response
*/
public function index()
{
$value = Cache::get('key');
//
}
}
使用Cache
門面,你可以使用store
方法訪問不同的緩存存儲器,傳入store
方法的鍵就是cache配置文件中stores
配置數(shù)組里列出的相應的存儲器:
$value = Cache::store('file')->get('foo');
Cache::store('redis')->put('bar', 'baz', 10);
Cache
門面的get
方法用于從緩存中獲取緩存項,如果緩存項不存在,返回null。如果需要的話你可以傳遞第二個參數(shù)到get
方法指定緩存項不存在時返回的自定義默認值:
$value = Cache::get('key');
$value = Cache::get('key', 'default');
你甚至可以傳遞一個閉包作為默認值,如果緩存項不存在的話閉包的結果將會被返回。傳遞閉包允許你可以從數(shù)據(jù)庫或其它外部服務獲取默認值:
$value = Cache::get('key', function() {
return DB::table(...)->get();
});
has
方法用于判斷緩存項是否存在:
if (Cache::has('key')) {
//
}
increment
和decrement
方法可用于調(diào)整緩存中的整型數(shù)值。這兩個方法都可以接收第二個參數(shù)來指明緩存項數(shù)值增加和減少的數(shù)目:
Cache::increment('key');
Cache::increment('key', $amount);
Cache::decrement('key');
Cache::decrement('key', $amount);
有時候你可能想要獲取緩存項,但如果請求的緩存項不存在時給它存儲一個默認值。例如,你可能想要從緩存中獲取所有用戶,或者如果它們不存在的話,從數(shù)據(jù)庫獲取它們并將其添加到緩存中,你可以通過使用Cache::remember
方法實現(xiàn):
$value = Cache::remember('users', $minutes, function() {
return DB::table('users')->get();});
如果緩存項不存在,傳遞給remember
方法的閉包被執(zhí)行并且將結果存放到緩存中。
你還可以聯(lián)合remember
和forever
方法:
$value = Cache::rememberForever('users', function() {
return DB::table('users')->get();});
如果你需要從緩存中獲取緩存項然后刪除,你可以使用pull
方法,和get
方法一樣,如果緩存項不存在的話返回null:
$value = Cache::pull('key');
你可以使用Cache
?門面上的put
方法在緩存中存儲緩存項。當你在緩存中存儲緩存項的時候,你需要指定數(shù)據(jù)被緩存的時間(分鐘數(shù)):
Cache::put('key', 'value', $minutes);
除了傳遞緩存項失效時間,你還可以傳遞一個代表緩存項有效時間的PHP?Datetime
實例:
$expiresAt = Carbon::now()->addMinutes(10);
Cache::put('key', 'value', $expiresAt);
add
方法只會在緩存項不存在的情況下添加緩存項到緩存,如果緩存項被添加到緩存返回true
,否則,返回false
:
Cache::add('key', 'value', $minutes);
forever
方法用于持久化存儲緩存項到緩存,這些值必須通過forget
方法手動從緩存中移除:
Cache::forever('key', 'value');
你可以使用Cache
門面上的forget
方法從緩存中移除緩存項:
Cache::forget('key');
要使用自定義驅(qū)動擴展Laravel緩存,我們使用Cache
門面的extend
方法,該方法用于綁定定義驅(qū)動解析器到管理器,通常,這可以在服務提供者中完成。
例如,要注冊一個新的命名為“mongo”的緩存驅(qū)動:
<?php
namespace App\Providers;
use Cache;
use App\Extensions\MongoStore;
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ū)動名稱。該值對應配置文件config/cache.php
中的driver
選項。第二個參數(shù)是返回Illuminate\Cache\Repository
實例的閉包。該閉包中被傳入一個$app
實例,也就是服務容器的一個實例。
調(diào)用Cache::extend
可以在默認App\Providers\AppServiceProvider
中的boot
方法中完成,或者你也可以創(chuàng)建自己的服務提供者來存放該擴展——只是不要忘了在配置文件config/app.php
中注冊該提供者。
要創(chuàng)建自定義的緩存驅(qū)動,首先需要實現(xiàn)Illuminate\Contracts\Cache\Store
契約,所以,我們的MongoDB
緩存實現(xiàn)看起來像這樣子:
<?php
namespace App\Extensions;
class MongoStore implements \Illuminate\Contracts\Cache\Store{
public function get($key) {}
public function put($key, $value, $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)完成后,我們可以完成自定義驅(qū)動注冊:
Cache::extend('mongo', function($app) {
return Cache::repository(new MongoStore);
});
擴展完成后,只需要更新配置文件config/cache.php
的driver
選項為你的擴展名稱。
如果你在擔心將自定義緩存驅(qū)動代碼放到哪,考慮將其放到Packgist!或者,你可以在app
目錄下創(chuàng)建一個Extensions
命名空間。然而,記住Laravel并沒有一個嚴格的應用目錄結構,你可以基于你的需要自由的組織目錄結構。
注意:緩存標簽不支持
file
或database
緩存驅(qū)動,此外,在“永久”存儲緩存中使用多個標簽時,memcached
之類的驅(qū)動有著最佳性能,因為它可以自動清除過期的記錄。
緩存標簽允許你給相關的緩存項打上同一個標簽,然后可以輸出被分配同一個標簽的所有緩存值。你可以通過傳遞一個有序的標簽名數(shù)組來訪問被打上標簽的緩存。例如,讓我們訪問一個被打上標簽的緩存并將其值放到緩存中:
Cache::tags(['people', 'artists'])->put('John', $john, $minutes);
Cache::tags(['people', 'authors'])->put('Anne', $anne, $minutes);
然而,并不只限于使用put
方法,你可以在處理標簽時使用任何混存存儲器提供的方法。
要獲取被打上標簽的緩存項,傳遞同樣的有序標簽名數(shù)組到tags
方法:
$john = Cache::tags(['people', 'artists'])->get('John');
$anne = Cache::tags(['people', 'authors'])->get('Anne');
通過上面的語句你可以輸出所有分配了該標簽或標簽列表的緩存項,例如,下面這個語句將會移除被打上people
,authors
標簽的緩存,或者,Anne
?和?John
都會從緩存中移除:
Cache::tags(['people', 'authors'])->flush();
相比之下,下面這個語句只會移除被打上?authors
標簽的緩存,所以John
會被移除,而Anne
不會:
Cache::tags('authors')->flush();
要在每次緩存操作時執(zhí)行代碼,你可以監(jiān)聽緩存觸發(fā)的事件,通常,你可以將這些緩存處理器代碼放到EventServiceProvider
的boot
方法中:
/**
* 注冊應用任意其他事件
*
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*/
public function boot(DispatcherContract $events){
parent::boot($events);
$events->listen('cache.hit', function ($key, $value) {
//
});
$events->listen('cache.missed', function ($key) {
//
});
$events->listen('cache.write', function ($key, $value, $minutes) {
//
});
$events->listen('cache.delete', function ($key) {
//
});
}
更多建議: