# 前言
學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法
; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣造一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 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 中存入 keyJohn
, 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 中取得 keyJohn
, 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:
移除有著 tagspeople, 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:
移除有著 tagsauthors
的 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, 將 keyfoo
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 內的 keyfoo
並 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 中的 keyfoo
並 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:
透過 implementIlluminate\Contracts\Cache\Store
, 可自定義一個 Cache Store, 可參考 MemcachedStore 的 source code
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
留言