Laravel 5.8 キャッシュ

設定

Laravelは読み書きしやすい、多くのキャッシュシステムに対する統一したAPIを提供します。キャッシュの設定は、config/cache.phpで指定します。アプリケーション全体のデフォルトとして使用するキャッシュドライバをこのファイルの中で指定します。MemcachedRedisなど、人気のあるキャッシュシステムをLaravelは最初からサポートしています。

キャッシュ設定ファイルは、様々な他のオプションも含んでいます。コメントで説明してありますので、よく読んで確認してください。Laravelのデフォルトとして、fileキャッシュドライバが設定されています。ファイルシステムへオブジェクトをシリアライズして保存します。大きなアプリケーションではMemecachedやAPCのような、より堅牢なドライバを使うことをおすすめします。複数のドライバを使用するキャッシュ設定も可能です。

ドライバ事前要件

データベース

データベースをキャッシュドライバに使用する場合、キャッシュアイテムを構成するテーブルを用意する必要があります。このテーブルの「スキーマ」を定義するサンプルを見てください。

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

Tip!! 正確なスキーマのマイグレーションを生成するために、php artisan cache:table Artisanコマンドを使用することもできます。

Memcached

Memcachedキャッシュを使用する場合は、Memcached PECLパッケージをインストールする必要があります。全Memcachedサーバは、config/cache.php設定ファイルにリストしてください。

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

さらに、UNIXソケットパスへ、hostオプションを設定することもできます。これを行うにはportオプションに0を指定してください。

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

Redis

LaravelでRedisを使う前に、Composerでpredis/predisパッケージ(~1.0)、もしくはPECLでPhpRedis PHP拡張のどちらかをインストールしておく必要があります。

Redisの設定についての詳細は、Laravelドキュメントページを読んでください。

キャッシュの使用法

キャッシュインスタンスの取得

Illuminate\Contracts\Cache\FactoryIlluminate\Contracts\Cache\Repository契約は、Laravelのキャッシュサービスへのアクセスを提供します。Factory契約は、アプリケーションで定義している全キャッシュドライバへのアクセスを提供します。Repository契約は通常、cache設定ファイルで指定している、アプリケーションのデフォルトキャッシュドライバの実装です。

しかし、このドキュメント全体で使用している、Cacheファサードも利用できます。Cacheファサードは裏で動作している、Laravelキャッシュ契約の実装への便利で簡潔なアクセスを提供しています。

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Cache;

class UserController extends Controller
{
    /**
     * アプリケーションの全ユーザーリストの表示
     *
     * @return Response
     */
    public function index()
    {
        $value = Cache::get('key');

        //
    }
}

複数のキャッシュ保存先へのアクセス

Cacheファサードのstoreメソッドを使い、様々なキャッシュ保存域へアクセスできます。storeメソッドに渡すキーは、cache設定ファイルのstores設定配列にリストしている保存域の一つです。

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

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

キャッシュからアイテム取得

Cacheファサードのgetメソッドは、キャッシュからアイテムを取得するために使用します。アイテムがキャッシュに存在していない場合は、nullが返されます。アイテムが存在していない時に返したい、カスタムデフォルト値をgetメソッドの第2引数として渡すこともできます。

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

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

デフォルト値として「クロージャ」を渡すこともできます。キャッシュに指定したアイテムが存在していない場合、「クロージャ」の結果が返されます。クロージャを渡すことで、データベースや外部サービスからデフォルト値を取得するのを遅らせることができます。

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

アイテムの存在確認

hasメソッドで、キャッシュにアイテムが存在しているかを調べることができます。このメソッドは、値がnullの場合、falseを返します。

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

値の増減

incrementdecrementメソッドはキャッシュの整数アイテムの値を調整するために使用します。両方のメソッドともそのアイテムの値をどのくらい増減させるかの増分をオプションの第2引数に指定できます。

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

取得不可時更新

キャッシュからアイテムを取得しようとして、指定したアイテムが存在しない場合は、デフォルト値を保存したい場合もあるでしょう。たとえば、全ユーザーをキャッシュから取得しようとし、存在していない場合はデータベースから取得しキャッシュへ追加したい場合です。Cache::rememberメソッドを使用します。

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

キャッシュに存在しない場合、rememberメソッドに渡された「クロージャ」が実行され、結果がキャッシュに保存されます。

rememberForeverメソッドでアイテムをキャッシュから取得するか、できない場合は永久に保存できます。

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

取得後削除

キャッシュからアイテムを取得した後に削除したい場合は、pullメソッドを使用します。getメソッドと同様にキャッシュにアイテムが存在していない場合は、nullが返ります。

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

キャッシュへアイテム保存

Cacheファサードのputメソッドにより、キャッシュにアイテムを保存できます。

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

putメソッドに保存期間を渡さない場合、そのアイテムは無期限に保存されます。

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

どのくらいでアイテムが無効になるかを秒数で指定する代わりに、キャッシュされたアイテムの有効期限を示すDateTimeインスタンスを渡すこともできます。

Cache::put('key', 'value', now()->addMinutes(10));

非存在時保存

addメソッドはキャッシュに保存されていない場合のみ、そのアイテムを保存します。キャッシュに実際にアイテムが追加された場合はtrueが返ってきます。そうでなければfalseが返されます。

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

アイテムを永遠に保存

foreverメソッドはそのアイテムをキャッシュへ永遠に保存します。こうした値は有効期限が切れないため、forgetメソッドを使用し、削除する必要があります。

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

Tip!! Memcachedドライバーを使用する場合、キャッシュが最大値に達すると、"forever"を指定したアイテムも削除されます。

キャッシュからのアイテム削除

forgetメソッドでキャッシュからアイテムを削除します。

Cache::forget('key');

0か負数を指定し、アイテムを削除することもできます。

Cache::put('key', 'value', 0);

Cache::put('key', 'value', -5);

キャッシュ全体をクリアしたい場合はflushメソッドを使います。

Cache::flush();

Note: flushメソッドは、キャッシュのプレフィックスを考慮せずに、キャッシュから全アイテムを削除します。他のアプリケーションと共有するキャッシュを削除するときは、利用を熟考してください。

アトミックロック

Note: この機能を利用するには、アプリケーションのデフォルトキャッシュドライバに、 memcacheddynamodbredisドライバを使用する必要があります。さらに、全てのサーバが同じ中央キャッシュサーバに接続する必要があります。

アトミックロックにより競合状態を心配することなく、分散型のロック操作を実現できます。たとえば、Laravel Forgeでは、一度に1つのリモートタスクを1つのサーバで実行するために、アトミックロックを使用しています。ロックを生成し、管理するにはCache::lockメソッドを使用します。

use Illuminate\Support\Facades\Cache;

$lock = Cache::lock('foo', 10);

if ($lock->get()) {
    // 10秒間ロックを獲得する

    $lock->release();
}

getメソッドは、クロージャも引数に取ります。クロージャ実行後、Laravelは自動的にロックを解除します。

Cache::lock('foo')->get(function () {
    // 無期限のロックを獲得し、自動的に開放する
});

リクエスト時にロックが獲得できないときに、指定秒数待機するようにLaravelに指示できます。指定制限時間内にロックが獲得できなかった場合は、Illuminate\Contracts\Cache\LockTimeoutExceptionが投げられます。

use Illuminate\Contracts\Cache\LockTimeoutException;

$lock = Cache::lock('foo', 10);

try {
    $lock->block(5);

    // 最大5秒待機し、ロックを獲得
} catch (LockTimeoutException $e) {
    // ロックを獲得できなかった
} finally {
    optional($lock)->release();
}

Cache::lock('foo', 10)->block(5, function () {
    // 最大5秒待機し、ロックを獲得
});

プロセス間のロック管理

あるプロセスでロックを獲得し、他のプロセスで開放したい場合もあります。たとえば、Webリクエストでロックを獲得し、そのリクエストから起動したキュー済みジョブの最後で、ロックを開放したい場合です。そのようなシナリオでは、ジョブで渡されたトークンを使い、ロックを再インスタンス化できるように、ロックを限定する「所有者(owner)のトークン」をキューするジョブへ渡す必要があります。

// コントローラ側
$podcast = Podcast::find($id);

$lock = Cache::lock('foo', 120);

if ($result = $lock->get()) {
    ProcessPodcast::dispatch($podcast, $lock->owner());
}

// ProcessPodcastジョブ側
Cache::restoreLock('foo', $this->owner)->release();

現在の所有者にかかわらず、ロックを開放したい場合は、forceReleaseメソッドを使用します。

Cache::lock('foo')->forceRelease();

cacheヘルパ

CacheファサードとCache契約に付け加え、キャッシュからのデータ取得/保存を行う、グローバルcache関数も使用できます。cache関数を文字列引数一つで呼び出す場合、指定したキーの値を返します。

$value = cache('key');

キー/値ペアの配列と、有効期間を関数へ渡す場合、指定期間の間、値をキャッシュへ保存します。

cache(['key' => 'value'], $seconds);

cache(['key' => 'value'], now()->addMinutes(10));

cache関数を引数なしで呼び出すと、Illuminate\Contracts\Cache\Factoryを実装したインスタンスが返ってきます。これを使い、他のキャッシュメソッドを呼び出せます。

cache()->remember('users', $seconds, function () {
    return DB::table('users')->get();
});

グローバルcache関数への呼び出しをテストする場合、ファサードのテストと同様に、Cache::shouldReceiveメソッドを使います。

キャッシュタグ

Note: filedatabaseキャッシュドライバ使用時、キャッシュタグはサポートされません。また、"forever"を使い、複数のタグをつけたキャッシュを使用する場合、古いレコードを自動的にパージするmemcachedのようなドライバがパフォーマンス的に最適です。

タグ付けキャッシュアイテムの保存

キャッシュタグにより、キャッシュ中の関連するアイテムへタグ付けできます。その後、指定したタグがつけられたキャッシュの値を全部削除できます。タグを順番に指定する配列を渡すことで、タグ付けしたキャッシュへアクセスできます。例としてタグ付けしたキャッシュにアクセスし、キャッシュへ値をputしてみましょう。

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

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

タグ付けキャッシュアイテムへのアクセス

タグ付けしたキャッシュアイテムを取得するには、tagsメソッドに同じ順序でタグのリストを渡し、続けてgetメソッドで取得したいキーを指定します。

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

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

タグ付けキャッシュアイテムの削除

タグ一つ、もしくはタグのリストに結びついた全アイテムを一度に消去することができます。たとえば、次の実行文はpeopleauthorsのどちらか、または両方にタグ付けされたキャッシュを全部削除します。ですから、AnneJohnは両方共キャッシュから削除されます。

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

対照的に、次の実行分ではauthorsにタグ付けしたキャッシュのみ削除されますので、Anneが削除され、Johnは残ります。

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

カスタムキャッシュドライバの追加

ドライバープログラミング

カスタムキャッシュドライバを作成するには、Illuminate\Contracts\Cache\Store契約を最初に実装する必要があります。そのため、MongoDBキャッシュドライバは、以下のような実装になるでしょう。

<?php

namespace App\Extensions;

use Illuminate\Contracts\Cache\Store;

class MongoStore implements Store
{
    public function get($key) {}
    public function many(array $keys) {}
    public function put($key, $value, $seconds) {}
    public function putMany(array $values, $seconds) {}
    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接続を用い、実装するだけです。各メソッドをどのように実装するかの例は、フレームワークのIlluminate\Cache\MemcachedStoreのソースコードを参照してください。実装を完了したら、ドライバを登録します。

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

Tip!! カスタムキャッシュドライバーをどこに設置するか迷っているなら、appディレクトリ下にExtensionsの名前空間で作成できます。しかし、Laravelはアプリケーション構造を強制していませんので、自分の好みに合わせてアプリケーションを自由に構築できることを忘れないでください。

ドライバ登録

Laravelにカスタムキャッシュドライバを登録するには、Cacheファサードのextendメソッドを使います。新しくインストールしたLaravelに含まれている、デフォルトのApp\Providers\AppServiceProviderbootメソッドで、Cache::extendを呼び出せます。もしくは、拡張を設置するために自身のサービスプロバイダを作成することもできます。config/app.phpプロバイダ配列に、そのプロバイダを登録し忘れないようにしてください。

<?php

namespace App\Providers;

use App\Extensions\MongoStore;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\ServiceProvider;

class CacheServiceProvider extends ServiceProvider
{
    /**
     * コンテナ結合の登録
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * 全アプリケーションサービスの初期起動
     *
     * @return void
     */
    public function boot()
    {
        Cache::extend('mongo', function ($app) {
            return Cache::repository(new MongoStore);
        });
    }
}

extendメソッドの最初の引数はドライバ名です。これはconfig/cache.php設定ファイルの、driverオプションと対応します。第2引数は、Illuminate\Cache\Repositoryインスタンスを返すクロージャです。クロージャには、サービスコンテナインスタンスの$appインスタンスが渡されます。

拡張を登録したら、config/cache.php設定ファイルのdriverオプションへ、拡張の名前を登録してください。

イベント

全キャッシュ操作に対してコードを実行するには、キャッシュが発行するイベントを購読する必要があります。通常、イベントリスナはEventServiceProviderの中へ設置します。

/**
 * アプリケーションのイベントリスナ
 *
 * @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',
    ],
];

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる