laravel 基礎(chǔ)教程 —— 緩存

緩存

配置

Laravel 對(duì)多種緩存系統(tǒng)提供了統(tǒng)一的 API。緩存的配置文件存放在 config/cache.php。你可以在這個(gè)文件中指定整個(gè)應(yīng)用默認(rèn)使用何種緩存驅(qū)動(dòng)。Laravel 支持當(dāng)前主流的緩存系統(tǒng)如 Memcached 和 Redis。

緩存的配置文件也包含了一些額外的配置選項(xiàng),這些選項(xiàng)在文件中都有文檔注釋,你應(yīng)該確保自己已經(jīng)讀了這些選項(xiàng)注釋。默認(rèn)的,Laravel 配置使用 file 緩存驅(qū)動(dòng),該驅(qū)動(dòng)會(huì)在文件系統(tǒng)中存儲(chǔ)序列化的緩存對(duì)象。對(duì)于大型應(yīng)用,建議使用內(nèi)存級(jí)的緩存,如 Memcached 或者 APC。你甚至可以在 laravel 中配置多種緩存配置到相同的驅(qū)動(dòng)。

緩存先決條件

數(shù)據(jù)庫

當(dāng)使用 database 緩存驅(qū)動(dòng)時(shí),你需要建立一個(gè)表來包含這些緩存項(xiàng)。你可以根據(jù)下面的 Schema 定義來建立表文件:

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

你也可以通過使用 php artisan cache:table Artisan 命令來生成正確的緩存表結(jié)構(gòu)遷移。

Memcached

使用 Memcached 緩存需要安裝 Memcached PECL package

默認(rèn)的配置基于 Memcached::addServer 使用 TCP/IP:

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

你也可以使用 UNIX socket 路徑來設(shè)置 host。如果你這么做,你需要設(shè)置 port0:

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

Redis

在你使用 Redis 緩存之前,你需要先通過 Composer 安裝 predis/predis。
關(guān)于更多的 Redis 配置信息,你可以參考 Laravel documentation page。

緩存使用

獲取緩存實(shí)例

Illuminate\Contracts\Cache\FactoryIlluminate\Contracts\Cache\Repository 契約提供對(duì) Laravel 緩存服務(wù)的訪問。Factory 契約提供了應(yīng)用中所有緩存驅(qū)動(dòng)的定義。Repository 契約通常是一個(gè)基于你的 cache 配置文件所使用的默認(rèn)緩存驅(qū)動(dòng)的實(shí)現(xiàn)。

事實(shí)上,你也可以使用 Cache 假面,在這篇文檔中,我們都是使用 Cache 假面進(jìn)行舉例。Cache 假面提供了一種方便簡潔的方式來訪問 Laravel 底層緩存契約的實(shí)現(xiàn)。

例如,讓我們引入 Cache 假面到控制器:

<?php

namespace App\Http\Controllers;

use Cache;

class UserController extends Controller 
{
  /**
   * Show a list of all users of the application.
   *
   * @return Response
   */
   public function index()
   {
     $value = Cache::get('key');

     //
   }
}

訪問多種緩存存儲(chǔ)

你可以通過 Cache 假面的 store 方法來訪問多種緩存存儲(chǔ)。傳遞到 store 方法的 key 應(yīng)該與你的 cache 配置文件中的 stores 配置項(xiàng)的列表之一相匹配:

$value = Cache::store('file')->get('foo');

Cache::store('redis')->put('bar', 'baz', 10);

獲取緩存項(xiàng)

你可以通過使用 Cache 假面的 get 方法來從緩存中獲取相關(guān)項(xiàng)的值。如果該項(xiàng)在緩存中并不存在,則返回 null 。如果你需要,你也可以傳遞第二個(gè)參數(shù)到 get 方法,這個(gè)參數(shù)所傳遞的值會(huì)在緩存中項(xiàng)不存在時(shí)被返回:

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

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

你甚至可以傳遞 Closure 作為默認(rèn)值。如果緩存的項(xiàng)不存在,Closure 所返回的值將被做為默認(rèn)值。傳遞閉包的方式可以使你從數(shù)據(jù)庫或者其他外部服務(wù)中延遲獲取默認(rèn)值:

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

檢查項(xiàng)是否存在

你可以使用 has 方法來檢查緩存中是否存在該項(xiàng):

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

遞增/遞減項(xiàng)中的值

你可以使用 incrementdecrement 方法來調(diào)整緩存項(xiàng)目中的整型值。這兩個(gè)方法都可以接受一個(gè)數(shù)組作為第二個(gè)參數(shù)來進(jìn)行相應(yīng)的數(shù)值調(diào)整:

Cache::increment('key');

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

Cache::decrement('key');

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

檢索或更新緩存中的項(xiàng)

有時(shí)候,你可能希望從緩存中檢索出一個(gè)項(xiàng)目,但是當(dāng)該項(xiàng)不存在的時(shí)候,你也想存儲(chǔ)一個(gè)默認(rèn)值到該項(xiàng)。比如,你希望從緩存中檢索出一個(gè)用戶。但是他并不存在,所以你需要從數(shù)據(jù)庫中獲取到他,然后添加到緩存中。你可以使用 Cache::remember 方法來做到這些:

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

如果緩存中沒有檢索到該項(xiàng),傳遞到 remeber 方法中的閉包將會(huì)被執(zhí)行并且其執(zhí)行結(jié)果將會(huì)在緩存中進(jìn)行替換。

你也可以合并 rememberforever 方法:

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

檢索并刪除

如果你需要檢索一個(gè)項(xiàng)目,并在檢索到的同時(shí)從緩存中刪除該項(xiàng),你可以使用 pull 方法。就像 get 方法一樣,如果未檢索到該項(xiàng),將會(huì)返回 null :

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

存儲(chǔ)項(xiàng)目到緩存

你可以使用 Cache 假面的 put 方法來存儲(chǔ)項(xiàng)目到緩存中。當(dāng)你存儲(chǔ)一個(gè)項(xiàng)到緩存中時(shí),你需要指定一個(gè)該項(xiàng)需要被緩存的分鐘值:

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

除了傳遞一個(gè)數(shù)值作為緩存過期的分鐘值,你也可以通過傳遞一個(gè) PHP DateTime 實(shí)例來設(shè)置緩存的失效時(shí)間:

$expiresAt = Carbon::now()->addMinutes(10);

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

add 方法只會(huì)在相應(yīng)的項(xiàng)在緩存中不存在時(shí)才會(huì)被添加進(jìn)緩存。該方法會(huì)在項(xiàng)目被添加到緩存后返回 true。否則返回 false

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

forever 方法可以用來將項(xiàng)目永久的添加進(jìn)緩存。該值只有手動(dòng)的使用 forget 方法才能被移除:

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

從緩存中移除項(xiàng)目

你可以使用 Cache 假面的 forget 方法來從緩存中移除某項(xiàng):

Cache::forget('key');

你可以使用 flush 方法來擦除所有的緩存:

Cache::flush();

擦除緩存并不會(huì)根據(jù)前綴來進(jìn)行智能擦除,它會(huì)移除所有的緩存。所以如果你的應(yīng)用和其他的應(yīng)用共享緩存,你應(yīng)該謹(jǐn)慎的使用該方法。

緩存標(biāo)簽

注意: 緩存標(biāo)簽并不支持 file 或者 database 緩存驅(qū)動(dòng)。另外,對(duì)于將多種標(biāo)簽標(biāo)記為永久存儲(chǔ)的驅(qū)動(dòng),性能最好的是能夠提供自動(dòng)清除過期記錄的驅(qū)動(dòng),比如 memcached。

存儲(chǔ)標(biāo)記了的項(xiàng)目到緩存

緩存標(biāo)簽允許你將相關(guān)的項(xiàng)目進(jìn)行關(guān)聯(lián)標(biāo)記。并且允許一次性清除所有給定標(biāo)簽的緩存項(xiàng)。你可以通過有序的標(biāo)簽數(shù)組來訪問被標(biāo)記的緩存項(xiàng)目。比如,讓我們?cè)L問被標(biāo)記的項(xiàng)目并使用 put 方法來設(shè)置緩存值:

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

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

事實(shí)上,你并沒有被限制只使用 put 方法。你可以在標(biāo)簽中使用任意的緩存存儲(chǔ)方法。

訪問被標(biāo)記的緩存項(xiàng)

為了訪問被標(biāo)記了的緩存項(xiàng),你需要傳遞相應(yīng)的有序列表到 tags 方法:

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

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

你可以一次性的擦除分配的標(biāo)記或者標(biāo)記列表中的所有項(xiàng)。比如,你可以使用 flush 方法來刪除所有的 peopleauthors 標(biāo)簽和兩者組成的有序列標(biāo)簽里的所有緩存項(xiàng)。所以,AnneJohn 都會(huì)被從緩存中移除:

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

下面的語句將會(huì)作為上面語句的對(duì)照,將只會(huì)從緩存中刪除 authors 標(biāo)簽的項(xiàng)目,所以 Anne 會(huì)被刪除,而 John 被保留:

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

添加自定義的緩存驅(qū)動(dòng)

為了在自定義的緩存驅(qū)動(dòng)中繼承 laravel 的緩存。我們需要使用 Cache 假面的 extend 方法,該方法被用來綁定自定義緩存到底層管理中。通常這些都是在服務(wù)提供者中完成。

比如,注冊(cè)一個(gè)新的緩存驅(qū)動(dòng)并命名為 'mongo':

<?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()
    {
      //
    }
}

第一個(gè)被傳遞到 extend 方法中的參數(shù)應(yīng)該是驅(qū)動(dòng)的名稱。這個(gè)名稱應(yīng)該和你的 config/cache.php 配置文件中的 driver 選項(xiàng)一致。而第二個(gè)參數(shù)是一個(gè)閉包,該閉包應(yīng)該返回一個(gè) Illuminate\Cache\Repository 的實(shí)現(xiàn)。在閉包中將會(huì)被傳遞一個(gè) $app 實(shí)例,這個(gè)實(shí)例是 laravel 中的服務(wù)容器的實(shí)例。

Cache::extend 方法的調(diào)用應(yīng)該在 App\Providers\AppServiceProviderboot 方法中完成?;蛘吣憧梢詣?chuàng)建自己的服務(wù)提供者來存儲(chǔ)這個(gè)擴(kuò)展。但是不要忘記在 config/app.php 文件中進(jìn)行注冊(cè)。

為了創(chuàng)建我們自己的緩存驅(qū)動(dòng),我們首先需要實(shí)現(xiàn) Illuminate\Constracts\Cache\Store 契約的接口。所以,我們的 MongoDB 緩存實(shí)現(xiàn)應(yīng)該看起來像這樣:

<?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 連接來實(shí)現(xiàn)這些方法。一旦我們的實(shí)現(xiàn)完成,我們就可以完成自己的緩存驅(qū)動(dòng)的注冊(cè):

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

然后在 config/cache.php 配置文件中更新驅(qū)動(dòng)為的名稱 driver 為你的擴(kuò)展的名稱。

如果你在為自定義的緩存文件應(yīng)該存放在哪里而疑惑,你可以考慮將其發(fā)布到 Packagist!或者,你可以在 app 目錄中創(chuàng)建一個(gè) Extensions 命名空間。事實(shí)上,你應(yīng)該謹(jǐn)記,laravel 并不死板的限制你的目錄結(jié)構(gòu),你應(yīng)該可以根據(jù)自己的習(xí)慣自由的管理你的應(yīng)用目錄結(jié)構(gòu)。

事件

如果你想在任何緩存被操作時(shí)執(zhí)行額外的代碼,你可能需要監(jiān)聽緩存的觸發(fā)事件。通常的你應(yīng)該存放這些事件監(jiān)聽器到你的 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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、配置 Laravel 為不同的緩存系統(tǒng)提供了統(tǒng)一的 API。緩存配置位于 config/cache.php。在...
    layjoy閱讀 997評(píng)論 0 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 原文鏈接 必備品 文檔:Documentation API:API Reference 視頻:Laracasts ...
    layjoy閱讀 8,696評(píng)論 0 121
  • 測(cè)試 簡介 測(cè)試是 Laravel 構(gòu)建的核心理念。事實(shí)上,Laravel 開箱即用的支持 PHPUnit 測(cè)試,...
    Dearmadman閱讀 8,178評(píng)論 2 28
  • 簡介 laravel 使實(shí)施認(rèn)證的變得非常簡單,事實(shí)上,它提供了非常全面的配置項(xiàng)以適應(yīng)應(yīng)用的業(yè)務(wù)。認(rèn)證的配置文件存...
    Dearmadman閱讀 6,330評(píng)論 2 13

友情鏈接更多精彩內(nèi)容