Ray Lee | 李宗叡
Learn or Die
Published in
20 min readDec 31, 2020

--

Photo by Denny Müller on Unsplash

# 版本

Laravel 8.x

# 前言

我喜歡使用 Laravel 開發的感覺, 除了開發快速, 程式碼簡潔且優雅之外, Laravel 框架本身也是一個很好的學習參照物。 本篇主要將官方文件重點整理成 Q&A 的形式呈現, 原子化的概念, 這方式並不適用於每個人, 但若對你有幫助, 我會很開心。

# 目錄

Laravel — 官方文件原子化翻譯 — 目錄

# 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, 會 throw LockTimeoutException, 如果有取得 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

--

--

Ray Lee | 李宗叡
Learn or Die

It's Ray. I do both backend and frontend, but more focus on backend. I like coding, and would like to see the whole picture of a product.