設定
Laravelは多くのキャッシュシステムに統一したAPIを提供します。キャッシュの設定はconfig/cache.php
で設定します。アプリケーション全体でデフォルトとして使用するキャッシュドライバーをこのファイルの中で指定します。MemcachedやRedisなど、人気のあるキャッシュシステムをLaravelは最初からサポートしています。
キャッシュ設定ファイルは様々な他のオプションも含んでいます。コメントで説明してありますのでよく読んで確認してください。Laravelのデフォルトとしてfile
キャッシュドライバーが設定されています。ファイルシステムにオブジェクトをシリアライズして保存します。大きなアプリケーションでは、MemecachedやAPCのようなメモリに保存するキャッシュを使用することをおすすめします。
キャッシュ動作要件
データベース
データベースをキャッシュドライバーに使用する場合、キャッシュアイテムを構成するテーブルを用意する必要があります。このテーブルの「スキーマ」を定義するサンプルを見てください。
Schema::create('cache', function($table) {
$table->string('key')->unique();
$table->text('value');
$table->integer('expiration');
});
Memcached
Memcachedキャッシュを使用する場合はMemcached PECLパッケージをインストールする必要があります。
デフォルト設定ではTCP/IPベースのMemcached::addServerを使用します。
'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キャシュを使用する場合、predis/predis
パッケージ(~1.0)をComposerでインストールしておく必要があります。
Redisの設定についての詳細はLaravelドキュメントページを読んでください。
キャッシュの使用法
キャッシュインスタンスの取得
Illuminate\Contracts\Cache\Factory
とIlluminate\Contracts\Cache\Repository
契約はLaravelのキャッシュサービスへのアクセスを提供します。Factory
契約はアプリケーションで定義している全キャッシュドライバーへのアクセスを提供します。Repository
契約は通常cache
設定ファイルで指定されているアプリケーションのデフォルトキャッシュドライバーの実装です。
しかしこのドキュメント全体で使用しているCache
ファサードも利用できます。Cache
ファサードは裏で動作しているLaravelキャッシュ契約の実装への便利で簡潔なアクセスを提供しています。
例としてコントローラーで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');
//
}
}
複数のキャッシュ保存先へのアクセス
Cache
ファサードのstore
メソッドを使い、様々なキャッシュ保存域へアクセスできます。store
メソッドに渡すキーはcache
設定ファイルのstores
設定配列にリストしている保存域の一つです。
$value = Cache::store('file')->get('foo');
Cache::store('redis')->put('bar', 'baz', 10);
キャッシュからアイテム取得
Cache
ファサードのget
メソッドはキャッシュからアイテムを取得するために使用します。アイテムがキャッシュに存在していない場合はnull
が返されます。アイテムが存在していない時に返したいカスタムデフォルト値をget
メソッドの第2引数として渡すこともできます。
$value = Cache::get('key');
$value = Cache::get('key', 'default');
デフォルト値として「クロージャー」を渡すこともできます。キャッシュに指定したアイテムが存在していない場合、「クロージャー」の結果が返されます。クロージャーを渡すことで、データベースや外部サービスからデフォルト値を取得するのを遅らせることができます。
$value = Cache::get('key', function() {
return DB::table(...)->get();
});
アイテムの存在確認
has
メソッドでキャッシュにアイテムが存在しているかを調べることができます。
if (Cache::has('key')) {
//
}
値の増減
increment
とdecrement
メソッドはキャッシュの整数アイテムの値を調整するために使用します。両方のメソッドともそのアイテムの値をどのくらい増減させるかの増分をオプションの第2引数に指定できます。
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();
});
キャッシュに存在しない場合、remember
メソッドに渡された「クロージャー」が実行され、結果がキャッシュに保存されます。
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');
You may clear the entire cache using the flush
method:
Cache::flush();
flush
メソッドはキャッシュのプレフィックスを考慮せずに、キャッシュから全アイテムを削除します。他のアプリケーションと共有するキャッシュを削除するときに、利用を考慮してください。
カスタムキャッシュドライバーの追加
Laravelキャッシュをカスタムドライバーで拡張するには、マネージャーにカスタムドライバーリゾルバ―を結合するために使用するCache
ファサードのextend
メソッドを使います。通常これはサービスプロバイダーの中で行います。
例として"mongo"という名前のキャッシュドライバーを登録してみましょう。
<?php
namespace App\Providers;
use Cache;
use App\Extensions\MongoStore;
use Illuminate\Support\ServiceProvider;
class CacheServiceProvider extends ServiceProvider
{
/**
* サービス初期処理登録後に実行
*
* @return void
*/
public function boot()
{
Cache::extend('mongo', function($app) {
return Cache::repository(new MongoStore);
});
}
/**
* コンテナ結合の登録
*
* @return void
*/
public function register()
{
//
}
}
extend
メソッドの最初の引数はドライバー名です。これはconfig/cache.php
設定ファイルのdriver
オプションと対応します。第2引数はIlluminate\Cache\Repository
インスタンスを返すクロージャーです。クロージャーにはサービスコンテナインスタンスの$app
インスタンスが渡されます。
Cache::extend
はインストールしたてのLaravelアプリケーションに含まれているデフォルトのApp\Providers\AppServiceProvider
のboot
メソッドで呼び出すか、もしくは拡張のためにサービスプロバイダーを新たに作成することもできるでしょう。この場合はサービスプロバイダーをconfig/app.php
のproviders配列へ登録するのを忘れないでください。
カスタムキャッシュドライバーを作成するには、最初にIlluminate\Contracts\Cache\Store
契約を実装する必要があります。ですからMongoDBキャシュの実装は次のような感じになるでしょう。
<?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接続を使い各メソッドを実装する必要があります。実装が完成したらカスタムドライバー登録を完了させましょう。
Cache::extend('mongo', function($app) {
return Cache::repository(new MongoStore);
});
拡張が完了したら、config/cache.php
設定ファイルのdriver
オプションを作成した拡張名に更新してください。
カスタムキャッシュドライバーコードをどこに設置するか迷っているのであれば、Packagistで公開することを考えてください! もしくはapp
ディレクトリーにExtensions
名前空間を作成することもできます。しかしLaravelは厳格なアプリケーション構造を持たないため、自分の好みに応じてアプリケーションを系統立てられることを忘れないでください。
キャッシュタグ
注意: キャッシュタグは
file
とdatabase
キャッシュドライバー使用時ではサポートされません。また、"forever"を使い複数のタグをつけたキャッシュを使用する場合、古いレコードを自動的にパージする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');
タグ一つ、もしくはタグのリストに結びついた全アイテムを一度に消去することができます。例えば、次の実行文はpeople
かauthors
のどちらか、または両方にタグ付けされたキャッシュを全部削除します。ですから、Anne
とJohn
は両方共キャッシュから削除されます。
Cache::tags(['people', 'authors'])->flush();
対照的に、次の実行分ではauthors
にタグ付けしたキャッシュのみ削除されますので、Anne
が削除され、John
は残ります。
Cache::tags('authors')->flush();
キャッシュイベント
キャッシュ操作が起きるごとにコードを実行するには、キャッシュにより発行されるイベントをリッスンしてください。通常、EventServiceProvider
のboot
メソッドの中にイベントハンドラーを設置することになるでしょう。
/**
* アプリケーションのその他のイベントの登録
*
* @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) {
//
});
}