既然已經決定要以 Simple Cache (簡易快取機制) 來做為這次的實戰題目,原則上在 PHP 社群中有建議的規範就按照規範走,沒有就自由發揮。剛好 PSR-16 建議規範的對象就是為快取套件定義出統一的介面。
CacheInterface
介面一共有六個公開方法。(為了節省版面已將註解移除唷!)
<?php
namespace Psr\SimpleCache;
interface CacheInterface
{
public function set($key, $value, $ttl = null);
public function delete($key);
public function clear();
public function getMultiple($keys, $default = null);
public function setMultiple($values, $ttl = null);
public function deleteMultiple($keys);
public function has($key);
}
介面中各方法的說明如下:
方法 | 說明 |
---|---|
set | 設定快取。 |
delete | 刪除快取。 |
clear | 刪除所有快取。 |
getMultiple | 一次取得多個快取的值,以可遍歷的陣列回傳。 |
setMultiple | 以可遍歷的陣列一次設定多個快取。 |
deleteMultiple | 以可遍歷的陣列一次刪除多個快取 |
has | 檢查是否有該鍵值的快取存在。 |
介面中各方法的參數說明如下:
變數 | 型別 | 說明 |
---|---|---|
$key |
string | 快取資料的鍵名。 |
$value |
mixed | 快取資料的值。 |
$ttl |
int, DateInterva, null | 快取資料的有效時間,過期後快取資料會被刪除。 |
$default |
mixed | 預設值,取不到該鍵名的資料,則回傳預設的值。 |
$keys |
iterable | 可遍歷的陣列結構,鍵值的集合。 |
$values |
iterable | key => value 可遍歷的陣列結構 |
PSR-16 定義兩個異常處理介面。
<?php
namespace Psr\SimpleCache;
interface CacheException
{
}
一般情況下關於快取機制產生錯誤的情況,丟出此異常錯誤。
<?php
namespace Psr\SimpleCache;
interface InvalidArgumentException extends CacheException
{
}
參數有錯誤的情況,丟出此異常錯誤。
先初步規劃出此專案作品的目錄結構,不過最後的完成品有可能會再修改唷!
.
├── README.md
├── composer.json
├── composer.lock
├── vendor
├── src
│ └── SimpleCache
│ ├── Cache.php
│ ├── CacheProvider.php
│ ├── Driver
│ │ ├── File.php
│ │ ├── Mysql.php
│ │ ├── Redis.php
│ │ └── Sqlite.php
│ └── Exception
│ ├── CacheArgumentException.php
│ └── CacheException.php
└── tests
└── SimpleCache
├── CacheTest.php
└── CacheTestCase.php
名稱 | 性質 | 說明 |
---|---|---|
README.md | 檔案 | 這個檔案是進入專案 GitHub 儲存庫的首頁說明檔,以 Markdown 格式編寫。 |
composer.json | 檔案 | 套件的設定檔。 |
composer.lock | 檔案 | 執行 composer install 後自動產生的檔案。(應加入 .gitignore 從版控中略過) |
vender | 目錄 | Composer 的套件目錄。以本例,裡頭裝了單元測試套用 PHP UNIT 的套件(及其依賴套件)、PSR-16 的介面。(應加入 .gitignore 從版控中略過) |
src | 目錄 | 這個專案作品的原始檔目錄,但筆者的規劃是命名空間的基本目錄是從 src/SimpleCache 開始。這只是個人的習慣,因為筆者想要它和單元測試用的 tests 目錄對稱。 |
tests | 目錄 | 單元測試用目錄,在這一層會放初始化的檔案,以及單元測試完自動產生的報表資料夾等等。筆者不想檔案都混在一起,所以測試的 .php 都會在 tests/SimpleCache 。 |
PSR-16 的兩個異常處理介面,會放在 src/SimpleCache/Exception
這個目錄。而 CacheInterface
會先實作在 CacheProvider.php
中。
各個不同類型的資料存取媒介,放在 src/SimpleCache/Driver
目錄中。
CacheInterface
介面實作於 CacheProvider
抽像類別中。這個抽像類別將實作一般情況下處理 Cache 資料的邏輯。
範例:/day-16/src/SimpleCache/CacheProvider.php
<?php
declare(strict_types=1);
namespace Shieldon\SimpleCache;
use Psr\SimpleCache\CacheInterface;
abstract class CacheProvider implements CacheInterface
{
public function get($key, $default = null)
{
}
public function set($key, $value, $ttl = null)
{
}
public function delete($key)
{
}
public function clear()
{
}
public function has($key)
{
}
public function getMultiple($keys, $default = null)
{
}
public function setMultiple($values, $ttl = null)
{
}
public function deleteMultiple($keys)
{
}
}
範例:/day-16/src/SimpleCache/Exception/CacheArgumentException.php
<?php
declare(strict_types=1);
namespace Shieldon\SimpleCache\Exception;
use Psr\SimpleCache\InvalidArgumentException as InvalidArgumentExceptionInterface;
use InvalidArgumentException;
class CacheArgumentException extends InvalidArgumentException implements InvalidArgumentExceptionInterface
{
}
CacheArgumentException
這個類別繼承了 InvalidArgumentException
並實作了 Psr\SimpleCache\InvalidArgumentException
介面。
範例:/day-16/src/SimpleCache/Exception/CacheException.php
<?php
declare(strict_types=1);
namespace Shieldon\SimpleCache\Exception;
use Psr\SimpleCache\CacheException as CacheExceptionInterface;
use Exception;
class CacheException extends Exception implements CacheExceptionInterface
{
}
CacheException
這個類別繼承了 Exception
並實作了 Psr\SimpleCache\CacheException
介面。因為撞名了會有錯誤,所以用 as
關鍵字換成別名。
或許讀者們會疑惑,為什麼要實作兩個介面但內容是卻是空的類別。
雖然目前還不需要改寫繼承的類別中方法或屬性,這是為了讓其它依賴的類別在往後這兩個異常處理類別需要改寫繼承類別的方法或屬性的時候,能一致性地套用到其它依賴的類別中。
今天的進度是先把介面實作出來,把檔案架構定出來,就像建築工地要蓋房子前要先搭好鷹架,一層一層往上蓋。一個空殼出來了,接下來後幾天就是把它做出來。
本篇原始碼可在此瀏覽。我們明天見囉。
本文同步更新於 TerryL 部落格 Day 16 - PHP 套件設計實戰 (2) 介面及目錄結構,歡迎前往討論。