# 版本
# 前言
我喜歡使用 Laravel 開發的感覺, 除了開發快速, 程式碼簡潔且優雅之外, Laravel 框架本身也是一個很好的學習參照物。 本篇主要將官方文件重點整理成 Q&A 的形式呈現, 原子化的概念, 這方式並不適用於每個人, 但若對你有幫助, 我會很開心。
# 目錄
# Configuration
# Driver Prerequisites
# Database
以下的 Laravel example code 的意思是?
- Example:
<?php
Schema::create('cache', function ($table) {
$table->string('key')->unique();
$table->text('value');
$table->integer('expiration');
});
- Answer: 當使用的 Cache driver 為 database 時, 需建立 cache table
以下的 Laravel example CLI 的意思是?
- Example:
php artisan cache:table
- Answer: 當使用的 Cache driver 為 database 時, 需建立 cache table
# Memcached
Laravel 中, 當使用 Memcached 時, 需要安裝套件嗎?
需要 PECL 的 package, 可參考 Stackoverflow, ServerPilot
以下的 Laravel example code 的意思是?
- Example:
<?php
'memcached' => [
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
// 'host' => '/var/run/memcached/memcached.sock',
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],
- Answer: 當使用 memcached 為 cache driver 時, 可在 config/cache.php 自定義 host, post, weight 也可以使用 sock
# Redis
Laravel 中, 若要使用 redis, 可安裝哪兩種套件
- PhpRedis PHP extension via PECL
- predis/predis via Composer
# Cache Usage
# Obtaining A Cache Instance
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Cache;
class UserController extends Controller
{
public function index()
{
$value = Cache::get('key');
//
}
}
- Answer: 使用 Cache::get() 取得 cache 中該 key 的 value
# Accessing Multiple Cache Stores
以下的 Laravel example code 的意思是?
- Example:
<?php
$value = Cache::store('file')->get('foo');
Cache::store('redis')->put('bar', 'baz', 600); // 10 Minutes
- Answer: Laravel 支援多種 stores, 像是 apc, redis, database, array, memcached, 等等.. 使用 store() 可以指定接下來要使用的 store, 若無指定則使用 default store 存到
redis
cache, key 為bar
, value 為baz
, 有效時間為 600 seconds
Retrieving Items From The Cache
以下的 Laravel example code 的意思是?
- Example:
<?php
$value = Cache::get('key');
$value = Cache::get('key', 'default');
- Answer: 從 default cache 中取得指定 key 的 value, 若無此 key 則回傳 null 從 default cache 中取得指定 key 的 value, 若無此 key 則回傳 value
'default'
以下的 Laravel example code 的意思是?
- Example:
<?php
$value = Cache::get('key', function () {
return DB::table(...)->get();
});
- Answer: 從 default cache 中取得指定 key 的 value, 若無此 key 則執行 closure, 並回傳其 return value
# Checking For Item Existence
以下的 Laravel example code 的意思是?
- Example:
<?php
if (Cache::has('key')) {
//
}
- Answer: 判斷 default cache 中, 該
'key'
是否存在
# Incrementing / Decrementing Values
以下的 Laravel example code 的意思是?
- Example:
<?php
Cache::increment('key');
Cache::increment('key', $amount);
Cache::decrement('key');
Cache::decrement('key', $amount);
- Answer: increase 或 decrease 指定
'key'
的 value, arg2 為要 increase / decrease 的量
# Retrieve & Store
以下的 Laravel example code 的意思是?
- Example:
<?php
$value = Cache::remember('users', $seconds, function () {
return DB::table('users')->get();
});
- Answer: 嘗試從 default cache 中取得 key
'users'
的 value, 若 key'users'
不存在, 則執行 closure, 取得 closure 的回傳值, 同時將其存到 cache 中, 有效時間為 $seconds
以下的 Laravel example code 的意思是?
- Example:
<?php
$value = Cache::rememberForever('users', function () {
return DB::table('users')->get();
});
- Answer: 嘗試從 default cache 中取得 key
'users'
的 value, 若 key'users'
不存在, 則執行 closure, 取得 closure 的回傳值, 同時將其存到 cache 中, 沒有失效期限
# Retrieve & Delete
以下的 Laravel example code 的意思是?
- Example:
<?php
$value = Cache::pull('key');
- Answer: 嘗試從 default cache 中取得 key
'key'
的 value, 並將此 key / value 從 cache 中清除, 若 key'users'
不存在, 則回傳 null
# Storing Items In The Cache
以下的 Laravel example code 的意思是?
- Example:
<?php
Cache::put('key', 'value', $seconds = 10);
- Answer: 在 default cache 中存入
key / value
, 有效期限為 10 秒, 如果 $seconds 未定義, 將會無限期儲存
以下的 Laravel example code 的意思是?
- Example:
<?php
Cache::put('key', 'value', now()->addMinutes(10));
- Answer: 在 default cache 中存入
key / value
, 有效期限為從現在往後算起的十分鐘後, 若 arg3 未指定, 將會無限期儲存
# Store If Not Present
以下的 Laravel example code 的意思是?
- Example:
<?php
Cache::add('key', 'value', $seconds);
- Answer: 如果 key 在 default cache 中不存在, 則新增
key / value / 有效時間
, 如果真的有新增, 會回傳 true, 否則 false
# Storing Items Forever
以下的 Laravel example code 的意思是?
- Example:
<?php
Cache::forever('key', 'value');
- Answer: 在 default cache 內新增一筆 key / value, 有效時間為永久, 但如果 Memcached driver, 當達到 size limit, 可能會刪除 forever 檔案
# Removing Items From The Cache
以下的 Laravel example code 的意思是?
- Example:
<?php
Cache::forget('key');
- Answer: 從 default cache 內移除 key 為
'key'
這筆資料
以下的 Laravel example code 的意思是?
- Example:
<?php
Cache::put('key', 'value', 0);
Cache::put('key', 'value', -5);
- Answer: 當指定有效期限為
負數
時, 也有刪除的效果
以下的 Laravel example code 的意思是?
- Example:
<?php
Cache::flush();
- Answer: 刪除整個 default cache 的資料, 不會因為 prefix 而有所區隔, 會刪除整個 cache 內的資料
# The Cache Helper
以下的 Laravel example code 的意思是?
- Example:
<?php
$value = cache('key');
- Answer: 使用 cache function 取得 default cache 中指定的 key 的 value
以下的 Laravel example code 的意思是?
- Example:
<?php
cache(['key' => 'value'], $seconds);
cache(['key' => 'value'], now()->addMinutes(10));
- Answer: 使用 cache function, 當提供完整的參數:
key / value / 有效時間
, 會將此參數儲存到 default cache
以下的 Laravel example code 的意思是?
- Example:
<?php
cache()->remember('users', $seconds, function () {
return DB::table('users')->get();
});
- Answer: 使用 cache function, 當沒有帶入 args 時, 會回傳一個
Illuminate\Contracts\Cache\Factory
instance 試圖取出 key 為users
的 value, 若不存在, 執行 closure, 並將 closure 回傳值存到 default cache 當中, 有效期限為 $seconds
# Cache Tags
Laravel Cache 中, Cache Tags 不支援哪幾種 driver?
file, dynamodb, database
# Storing Tagged Cache Items
以下的 Laravel example code 的意思是?
- Example:
<?php
Cache::tags(['people', 'artists'])->put('John', $john, $seconds);
Cache::tags(['people', 'authors'])->put('Anne', $anne, $seconds);
- Answer: 在 default cache 中存入 key
John
, value$john
, 有效期限seconds
, 並 tag 這筆資料['people', 'artists']
# Accessing Tagged Cache Items
以下的 Laravel example code 的意思是?
- Example:
<?php
$john = Cache::tags(['people', 'artists'])->get('John');
$anne = Cache::tags(['people', 'authors'])->get('Anne');
- Answer: 從 default cache 中取得 key
John
, tags['people', 'artists']
的資料
# Removing Tagged Cache Items
以下的 Laravel example code 的意思是?
- Example:
<?php
Cache::tags(['people', 'artists'])->put('John', $john, $seconds);
Cache::tags(['people', 'authors'])->put('Anne', $anne, $seconds);
Cache::tags(['people', 'authors'])->flush();
- Answer: 移除有著 tags
people, authors
的 cache items, 所以 John 跟 Anne 都會被移除
以下的 Laravel example code 的意思是?
- Example:
<?php
Cache::tags(['people', 'artists'])->put('John', $john, $seconds);
Cache::tags(['people', 'authors'])->put('Anne', $anne, $seconds);
Cache::tags('authors')->flush();
- Answer: 移除有著 tags
authors
的 cache items, 所以 Anne 會被移除, John 不會
# Atomic Locks
# Driver Prerequisites
# Database
以下的 Laravel example code 的意思是?
- Example:
<?php
Schema::create('cache_locks', function ($table) {
$table->string('key')->primary();
$table->string('owner');
$table->integer('expiration');
});
- Answer: 當欲使用 Cache Lock, 且 driver 為 database 時, 需要新增 cache lock 用的 table
# Managing Locks
以下的 Laravel example code 的意思是?
- Example:
<?php
$lock = Cache::lock('foo', 10);
if ($lock->get()) {
// Lock acquired for 10 seconds...
$lock->release();
}
- Answer: 使用 Cache Lock, 將 key
foo
lock 10 秒後釋放, 這 10 秒內可以執行一些邏輯, 比如 transaction, 以避免 race condition
以下的 Laravel example code 的意思是?
- Example:
<?php
Cache::lock('foo')->get(function () {
// Lock acquired indefinitely and automatically released...
});
- Answer: 取得 default cache 中的 foo 並 lock 該 key, 然後執行 closure, 執行完後自動 release 該 lock
以下的 Laravel example code 的意思是?
- Example:
<?php
use Illuminate\Contracts\Cache\LockTimeoutException;
$lock = Cache::lock('foo', 10);
try {
$lock->block(5);
// Lock acquired after waiting maximum of 5 seconds...
} catch (LockTimeoutException $e) {
// Unable to acquire lock...
} finally {
optional($lock)->release();
}
- Answer: 嘗試取得 default cache 內的 key
foo
並 lock 10 秒, 如果 key 不可得, 會持續嘗試 5 秒, 若 5 秒過了仍然無法取得該 key, 會 throwLockTimeoutException
, 如果有取得 lock, 執行完定義的邏輯後, 會 release 該 lock
以下的 Laravel example code 的意思是?
- Example:
<?php
Cache::lock('foo', 10)->block(5, function () {
// Lock acquired after waiting maximum of 5 seconds...
});
- Answer: 嘗試取得 default cache 中的 key
foo
並 lock 10 秒, 如果 key 正被 lock 中, 會持續嘗試 5 秒取得 key, 若 5 秒仍沒取得, 會 throw LockTimeoutException, 若取得則會執行 closure, closure 執行完後會 release 該 key
# Managing Locks Across Processes
以下的 Laravel example code 的意思是?
- Example:
<?php
$podcast = Podcast::find($id);
$lock = Cache::lock('processing', 120);
if ($result = $lock->get()) {
ProcessPodcast::dispatch($podcast, $lock->owner());
}
// job hander 當中
Cache::restoreLock('processing', $this->owner)->release();
Cache::lock('processing')->forceRelease();
- Answer: 取得 key 為
processing
的 lock 之後, 鎖住 120 秒, 然後將$lock->owner()
pass 到一個 job 當中, 之後可以在該 job 當中透過 lock owner release 該 lock, 或強制 release 該 lock
以下的 Laravel example code 的意思是?
- Example:
<?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() {}
}
- Answer: 透過 implement
Illuminate\Contracts\Cache\Store
, 可自定義一個 Cache Store, 可參考 MemcachedStore 的 source code
以下的 Laravel example code 的意思是?
- Example:
<?php
Cache::extend('mongo', function ($app) {
return Cache::repository(new MongoStore);
});
- Answer: 使用自定義的 store, mongo 為在 AppServiceProvider register() 中, 註冊的名字
Laravel 中, 當我使用一個 extended Store 時, 可將自定義的 cache driver class 放在哪?
可放在 app\Extensions
資料夾中, 不過這只是官方建議, 實際上放哪都行
# Registering The Driver
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Providers;
use App\Extensions\MongoStore;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\ServiceProvider;
class CacheServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->booting(function () {
Cache::extend('mongo', function ($app) {
return Cache::repository(new MongoStore);
});
});
}
public function boot()
{
//
}
}
- Answer: 在 AppServiceProvider 的 register() 中, 註冊自定義的 cache store, extend() 的 arg1 為 store name, arg2 為 closure, 必須 return 一個
Illuminate\Cache\Repository
instance 註冊成功後就可以到config/cache.php
修改 driver name
Events
以下的 Laravel example code 的意思是?
- Example:
<?php
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',
],
];
- Answer: 各種預設的 Cache Events CacheHit: 當嘗試取得 cache 而有成功取得 CacheMissed: 當嘗試取得 Cache 而沒取得, 透過 closure 取得的不算有取得, 所以一樣算 missed KeyForgotten: 使用 cache:forget() keyWritten: 成功寫入 cache