# 前言
學習一個框架, 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
存到rediscache, 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\Factoryinstance
試圖取出 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, 將 keyfoolock 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\Repositoryinstance
註冊成功後就可以到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
留言