服務 ―― 緩存

2018-02-24 15:38 更新

服務 —— 緩存

1、配置

Laravel為不同的緩存系統(tǒng)提供了統(tǒng)一的API。緩存配置位于config/cache.php。在該文件中你可以指定在應用中默認使用哪個緩存驅(qū)動。Laravel目前支持流行的緩存后端如MemcachedRedis等。

緩存配置文件還包含其他文檔化的選項,確保仔細閱讀這些選項。默認情況下,Laravel被配置成使用文件緩存,這會將序列化數(shù)據(jù)和緩存對象存儲到文件系統(tǒng)。對大型應用,建議使用內(nèi)存緩存如Memcached或APC,你甚至可以為同一驅(qū)動配置多個緩存配置。

1.1 緩存預備知識

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

使用database緩存驅(qū)動時,你需要設置一張表包含緩存緩存項。下面是該表的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
    ],
],

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

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

1.1.3?Redis

使用Laravel的Redis緩存之前,你需要通過Composer安裝predis/predis包(~1.0)。

了解更多關于Redis的配置,查看Larave的Redis文檔。

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');

你甚至可以傳遞一個閉包作為默認值,如果緩存項不存在的話閉包的結果將會被返回。傳遞閉包允許你可以從數(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í)行并且將結果存放到緩存中。

你還可以聯(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并沒有一個嚴格的應用目錄結構,你可以基于你的需要自由的組織目錄結構。

4、緩存標簽

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

4.1 存儲打上標簽的緩存項

緩存標簽允許你給相關的緩存項打上同一個標簽,然后可以輸出被分配同一個標簽的所有緩存值。你可以通過傳遞一個有序的標簽名數(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標簽的緩存,或者,Anne?和?John都會從緩存中移除:

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) {
        //
    });
}
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號