緩衝
配置
Laravel 對多種緩衝系統提供了統一的 API。緩衝的設定檔存放在 config/cache.php。你可以在這個檔案中指定整個應用預設使用何種緩衝驅動。Laravel 支援當前主流的緩衝系統如 Memcached 和 Redis。
緩衝的設定檔也包含了一些額外的配置選項,這些選項在檔案中都有文檔注釋,你應該確保自己已經讀了這些選項注釋。預設的,Laravel 配置使用 file 緩衝驅動,該驅動會在檔案系統中儲存序列化的緩衝對象。對於大型應用,建議使用記憶體級的緩衝,如 Memcached 或者 APC。你甚至可以在 laravel 中配置多種緩衝配置到相同的驅動。
緩衝先決條件
資料庫
當使用 database 緩衝驅動時,你需要建立一個表來包含這些快取項目。你可以根據下面的 Schema 定義來建立表檔案:
Schema::create('cache', function ($table) { $table->string('key')->unique(); $table->text('value'); $table->integer('expiration'); });
你也可以通過使用 php artisan cache:table Artisan 命令來產生正確的緩衝表結構遷移。
Memcached
使用 Memcached 緩衝需要安裝 Memcached PECL package。
預設的配置基於 Memcached::addServer 使用 TCP/IP:
'memcached' => [ [ 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 100 ]],
你也可以使用 UNIX socket 路徑來設定 host。如果你這麼做,你需要設定 port 為 0:
'memcached' => [ [ 'host' => '/var/run/memcached/memcached.sock', 'port' => 0, 'weight' => 100 ],],
Redis
在你使用 Redis 緩衝之前,你需要先通過 Composer 安裝 predis/predis。關於更多的 Redis 配置資訊,你可以參考 Laravel documentation page。
緩衝使用
擷取緩衝執行個體
Illuminate\Contracts\Cache\Factory 和 Illuminate\Contracts\Cache\Repository 契約提供對 Laravel 快取服務的訪問。Factory 契約提供了應用中所有緩衝驅動的定義。Repository 契約通常是一個基於你的 cache 設定檔所使用的預設緩衝驅動的實現。
事實上,你也可以使用 Cache 假面,在這篇文檔中,我們都是使用 Cache 假面進行舉例。Cache 假面提供了一種方便簡潔的方式來訪問 Laravel 底層緩衝契約的實現。
例如,讓我們引入 Cache 假面到控制器:
訪問多種緩衝儲存
你可以通過 Cache 假面的 store 方法來訪問多種緩衝儲存。傳遞到 store 方法的 key 應該與你的 cache 設定檔中的 stores 配置項的列表之一相匹配:
$value = Cache::store('file')->get('foo');Cache::store('redis')->put('bar', 'baz', 10); 擷取快取項目
你可以通過使用 Cache 假面的 get 方法來從緩衝中擷取相關項目的值。如果該項在緩衝中並不存在,則返回 null 。如果你需要,你也可以傳遞第二個參數到 get 方法,這個參數所傳遞的值會在緩衝中項不存在時被返回:
$value = Cache::get('key');$value = Cache::get('key', 'default'); 你甚至可以傳遞 Closure 作為預設值。如果緩衝的項不存在,Closure 所返回的值將被做為預設值。傳遞閉包的方式可以使你從資料庫或者其他外部服務中延遲擷取預設值:
$value = Cache::get('key', function () { return DB::table(...)->get(); }); 檢查項是否存在
你可以使用 has 方法來檢查緩衝中是否存在該項:
if (Cache::has('key')) { //} 遞增/遞減項中的值
你可以使用 increment 和 decrement 方法來調整快取項目中的整型值。這兩個方法都可以接受一個數組作為第二個參數來進行相應的數值調整:
Cache::increment('key');Cache::increment('key', $amount);Cache::decrement('key');Cache::decrement('key', $amount); 檢索或更新緩衝中的項
有時候,你可能希望從緩衝中檢索出一個項目,但是當該項不存在的時候,你也想儲存一個預設值到該項。比如,你希望從緩衝中檢索出一個使用者。但是他並不存在,所以你需要從資料庫中擷取到他,然後添加到緩衝中。你可以使用 Cache::remember 方法來做到這些:
$value = Cache::remember('users', $minutes, function () { return DB::table('users')->get(); }); 如果緩衝中沒有檢索到該項,傳遞到 remeber 方法中的閉包將會被執行並且其執行結果將會在緩衝中進行替換。
你也可以合并 remember 和 forever 方法:
$value = Cache::rememberForever('users', function () { return DB::table('users')->get(); }); 檢索並刪除
如果你需要檢索一個項目,並在檢索到的同時從緩衝中刪除該項,你可以使用 pull 方法。就像 get 方法一樣,如果未檢索到該項,將會返回 null :
$value = Cache::pull('key'); 儲存項目到緩衝
你可以使用 Cache 假面的 put 方法來儲存項目到緩衝中。當你儲存一個項到緩衝中時,你需要指定一個該項需要被緩衝的分鐘值:
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'); 你可以使用 flush 方法來擦除所有的緩衝:
Cache::flush();
擦除緩衝並不會根據首碼來進行智能擦除,它會移除所有的緩衝。所以如果你的應用和其他的應用共用快取,你應該謹慎的使用該方法。
緩衝標籤
注意: 緩衝標籤並不支援 file 或者 database 緩衝驅動。另外,對於將多種標籤標記為永久儲存的驅動,效能最好的是能夠提供自動清除到期記錄的驅動,比如 memcached。
儲存標記了的項目到緩衝
緩衝標籤允許你將相關的項目進行關聯標記。並且允許一次性清除所有給定標籤的快取項目。你可以通過有序的標籤數組來訪問被標記的快取項目。比如,讓我們訪問被標記的項目並使用 put 方法來設定緩衝值:
Cache::tags(['people', 'artists'])->put('John', $john, $minutes);Cache::tags(['people', 'authors'])->put('Anne', $anne, $minutes); 事實上,你並沒有被限制只使用 put 方法。你可以在標籤中使用任意的緩衝儲存方法。
訪問被標記的快取項目
為了訪問被標記了的快取項目,你需要傳遞相應的有序列表到 tags 方法:
$john = Cache::tags(['people', 'artists'])->get('John');$anne = Cache::tags(['people', 'authors'])->get('Anne'); 你可以一次性的擦除分配的標記或者標記列表中的所有項。比如,你可以使用 flush 方法來刪除所有的 people 和 authors 標籤和兩者組成的有序欄標籤裡的所有快取項目。所以,Anne 和 John 都會被從緩衝中移除:
Cache::tags(['people', 'authors'])->flush();
下面的語句將會作為上面語句的對照,將只會從緩衝中刪除 authors 標籤的項目,所以 Anne 會被刪除,而 John 被保留:
Cache::tags('authors')->flush(); 添加自訂的緩衝驅動
為了在自訂的緩衝驅動中繼承 laravel 的緩衝。我們需要使用 Cache 假面的 extend 方法,該方法被用來綁定自訂緩衝到底層管理中。通常這些都是在服務提供者中完成。
比如,註冊一個新的緩衝驅動並命名為 'mongo':
第一個被傳遞到 extend 方法中的參數應該是驅動的名稱。這個名稱應該和你的 config/cache.php 設定檔中的 driver 選項一致。而第二個參數是一個閉包,該閉包應該返回一個 Illuminate\Cache\Repository 的實現。在閉包中將會被傳遞一個 $app 執行個體,這個執行個體是 laravel 中的服務容器的執行個體。
Cache::extend 方法的調用應該在 App\Providers\AppServiceProvider 的 boot 方法中完成。或者你可以建立自己的服務提供者來儲存這個擴充。但是不要忘記在 config/app.php 檔案中進行註冊。
為了建立我們自己的緩衝驅動,我們首先需要實現 Illuminate\Constracts\Cache\Store 契約的介面。所以,我們的 MongoDB 緩衝實現應該看起來像這樣:
我們僅僅需要使用 MongoDB 串連來實現這些方法。一旦我們的實現完成,我們就可以完成自己的緩衝驅動的註冊:
Cache::extend('mongo', function ($app) { return Cache::repository(new MongoStore); }); 然後在 config/cache.php 設定檔中更新驅動為的名稱 driver 為你的擴充的名稱。
如果你在為自訂的快取檔案應該存放在哪裡而疑惑,你可以考慮將其發布到 Packagist!或者,你可以在 app 目錄中建立一個 Extensions 命名空間。事實上,你應該謹記,laravel 並不死板的限制你的目錄結構,你應該可以根據自己的習慣自由的管理你的應用目錄結構。
事件
如果你想在任何緩衝被操作時執行額外的代碼,你可能需要監聽緩衝的觸發事件。通常的你應該存放這些事件監聽器到你的 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', ], ];