鍍金池/ 教程/ PHP/ 緩存
門面
Laravel Homestead
安裝及配置
測試
HTTP 中間件
加密
升級指南
幫助函數(shù)
應用目錄結(jié)構(gòu)
集合
新手入門指南-簡單任務管理系統(tǒng)
任務調(diào)度
查詢構(gòu)建器
視圖
驗證
Laravel Cashier(訂購&支付&發(fā)票)
本地化
隊列
調(diào)整器
分頁
文件系統(tǒng)/云存儲
貢獻代碼
哈希
HTTP 控制器
緩存
遷移
HTTP 請求
Laravel Elixir
發(fā)行版本說明
Envoy 任務運行器(SSH任務)
序列化
Session
起步
帶用戶功能的任務管理系統(tǒng)
起步
用戶授權(quán)
郵件
事件
填充數(shù)據(jù)
HTTP 路由
服務提供者
Blade 模板引擎
包開發(fā)
用戶認證
Artisan 控制臺
HTTP 響應
集合
服務容器
關(guān)聯(lián)關(guān)系
一次請求的生命周期
契約
Redis
錯誤&日志

緩存

1、配置

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

1.1 緩存預備知識

1.1.1 數(shù)據(jù)庫

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

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

1.1.2 Memcached

使用 Memcached緩存要求安裝了 Memcached PECL包,即 PHP Memcached擴展。 Memcached::addServer默認配置使用 TCP/IP 協(xié)議:

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

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

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

1.1.3 Redis

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

2、緩存使用

2.1 獲取緩存實例

Illuminate\Contracts\Cache\FactoryIlluminate\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');

        //
    }
}

2.1.1 訪問多個緩存存儲

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

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

2.2 從緩存中獲取數(shù)據(jù)

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

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

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

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

2.2.1 檢查緩存項是否存在

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

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

2.2.2 數(shù)值增加/減少

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

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

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

2.2.3 獲取或更新

有時候你可能想要獲取緩存項,但如果請求的緩存項不存在時給它存儲一個默認值。例如,你可能想要從緩存中獲取所有用戶,或者如果它們不存在的話,從數(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();});

2.2.4 獲取并刪除

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

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

2.3 存儲緩存項到緩存

你可以使用 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');

2.4 從緩存中移除數(shù)據(jù)

你可以使用 Cache門面上的 forget方法從緩存中移除緩存項:

Cache::forget('key');

3、添加自定義緩存驅(qū)動

要使用自定義驅(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.phpdriver選項為你的擴展名稱。 如果你在擔心將自定義緩存驅(qū)動代碼放到哪,考慮將其放到 Packgist!或者,你可以在 app目錄下創(chuàng)建一個 Extensions命名空間。然而,記住 Laravel并沒有一個嚴格的應用目錄結(jié)構(gòu),你可以基于你的需要自由的組織目錄結(jié)構(gòu)。

4、緩存標簽

注意:緩存標簽不支持 filedatabase緩存驅(qū)動,此外,在“永久”存儲緩存中使用多個標簽時,memcached之類的驅(qū)動有著最佳性能,因為它可以自動清除過期的記錄。

4.1 存儲打上標簽的緩存項

緩存標簽允許你給相關(guān)的緩存項打上同一個標簽,然后可以輸出被分配同一個標簽的所有緩存值。你可以通過傳遞一個有序的標簽名數(shù)組來訪問被打上標簽的緩存。例如,讓我們訪問一個被打上標簽的緩存并將其值放到緩存中:

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

然而,并不只限于使用 put方法,你可以在處理標簽時使用任何混存存儲器提供的方法。

4.2 訪問打上標簽的緩存項

要獲取被打上標簽的緩存項,傳遞同樣的有序標簽名數(shù)組到 tags方法:

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

通過上面的語句你可以輸出所有分配了該標簽或標簽列表的緩存項,例如,下面這個語句將會移除被打上 people,authors標簽的緩存,或者,AnneJohn都會從緩存中移除:

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

相比之下,下面這個語句只會移除被打上 authors標簽的緩存,所以 John會被移除,而 Anne不會:

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

5、緩存事件

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

/**
 * 注冊應用任意其他事件
 *
 * @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) {
        //
    });
}
上一篇:服務容器下一篇:郵件