1. 程式人生 > >PHP規範PSR6(Cache介面)介紹

PHP規範PSR6(Cache介面)介紹

快取是提高任何專案效能的常用方法,使快取庫成為許多框架和庫的最常見功能之一。這導致許多庫推出自己的快取庫,具有各種級別的功能。這些差異導致開發人員必須學習多個系統,這些系統可能會也可能不會提供他們所需的功能。此外,快取庫本身的開發人員面臨著只支援有限數量的框架或建立大量介面卡類的選擇。

快取系統的通用介面將解決這些問題。庫和框架開發人員可以按照他們期望的方式依賴快取系統,而快取系統的開發人員只需要實現一組介面而不是各種各樣的介面卡。

本文件中的關鍵詞“必須”,“必須”,“必需”,“應該”,“不應該”,“應該”,“不應該”,“推薦”,“可以”和“可選”按照RFC 2119中的描述進行解釋。

1 目標

此PSR的目標是允許開發人員建立可以整合到現有框架和系統中的快取感知庫,而無需自定義開發。

2 定義

  1. 呼叫庫 - 實際需要快取服務的庫或程式碼。該庫將利用實現此標準介面的快取服務,但不會知道這些快取服務的實現。
  2. 實現庫 - 該庫負責實現此標準,以便為任何呼叫庫提供快取服務。實現庫必須提供實現Cache \ CacheItemPoolInterface和Cache \ CacheItemInterface介面的類。實現庫必須支援至少TTL功能,如下所述,具有全秒級粒度。
  3. TTL - 專案的生存時間(TTL)是該專案儲存與被認為是陳舊之間的時間量。 TTL通常由表示以秒為單位的時間的整數或DateInterval物件定義。
  4. Expiration - 專案設定為失效的實際時間。這通常通過將TTL新增到儲存物件的時間來計算,但也可以使用DateTime物件顯式設定。在1:30:00儲存300秒TTL的專案將到期為1:35:00。實現庫可以在其請求的到期時間之前使專案到期,但是一旦達到其到期時間,必須將專案視為已過期。如果呼叫庫要求儲存專案但未指定過期時間,或指定空過期時間或TTL,則實現庫可以使用配置的預設持續時間。如果沒有設定預設持續時間,則實現庫必須將其解釋為永久快取專案的請求,或者只要底層實現支援。
  5. Key - 至少一個字元的字串,用於唯一標識快取的專案。實現庫必須支援由字元A-Z,a-z,0-9,_和組成的鍵。以UTF-8編碼的任何順序,長度最多為64個字元。實現庫可以支援其他字元和編碼或更長的長度,但必須至少支援該最小值。庫負責自己的Key轉義,但必須能夠返回原始未修改的Key字串。以下字元保留用於將來的擴充套件,並且實現庫不得支援:{}()/ \ @:
  6. Hit - 當呼叫庫按鍵請求Item並且找到該鍵的匹配值並且該值未過期時,會發生快取命中,並且由於某些其他原因該值無效。呼叫庫應該確保在所有get()呼叫上驗證isHit()。
  7. Miss - 快取未命中與快取命中相反。當呼叫庫按鍵請求專案並且找不到該鍵的值,或者找到但已過期的值,或者由於某些其他原因該值無效時,會發生快取未命中。過期的值必須始終被視為快取未命中。
  8. 延遲 - 延遲快取儲存表示池可能不會立即保留快取項。 Pool物件可以延遲持久化延遲快取專案,以便利用某些儲存引擎支援的批量設定操作。池必須確保最終持久化任何延遲快取項並且資料不會丟失,並且可以在呼叫庫請求它們被持久化之前保留它們。當呼叫庫呼叫commit()方法時,所有未完成的延遲項必須保持不變。實現庫可以使用適當的邏輯來確定何時持久化延遲項,例如物件解構函式,持久儲存save(),超時或最大項檢查或任何其他適當的邏輯。對已延遲的快取項的請求必須返回延遲但尚未持久的項

3 資料

實現庫必須支援所有可序列化的PHP資料型別,包括:

  1. 字串 - 任何PHP相容編碼中任意大小的字串。
  2. 整數 - PHP支援的任何大小的所有整數,最多64位簽名。
  3. 浮點數 - 所有帶符號的浮點值。
  4. 布林值 - 真和假。
  5. Null - 實際的空值。
  6. 陣列 - 任意深度的索引,關聯和多維陣列。
  7. Object - 支援無損序列化和反序列化的任何物件,以便$ o == unserialize(serialize($ o))。物件可以使用PHP的Serializable介面,__sleep()或__wakeup()魔術方法,或者適當的類似語言功能。

傳遞到實現庫的所有資料必須完全按照傳遞的方式返回。這包括變數型別。也就是說,返回(字串)5是錯誤的,如果(int)5是儲存的值。實現庫可以在內部使用PHP的serialize()/ unserialize()函式,但不是必須這樣做。與它們的相容性僅用作可接受物件值的基線。

如果由於任何原因無法返回確切的儲存值,則實現庫必須以快取未命中而不是損壞的資料進行響應。

4 關鍵概念

池表示快取系統中的專案集合。池是它包含的所有項的邏輯儲存庫。所有可快取的項都作為Item物件從Pool中檢索,並且所有與快取物件的全部互動都通過Pool進行。

專案

Item表示池中的單個鍵/值對。Key是Item的主要唯一識別符號,必須是不可變的。值可以隨時更改。

5 錯誤處理

雖然快取通常是應用程式效能的重要組成部分,但它永遠不應成為應用程式功能的關鍵部分。因此,快取系統中的錯誤不應導致應用程式失敗。因此,實現庫絕不能丟擲除介面定義的異常之外的異常,並且應該捕獲由底層資料儲存觸發的任何錯誤或異常,並且不允許它們冒泡。

實施庫應該記錄這些錯誤或以適當方式將其報告給管理員。

如果呼叫庫請求刪除一個或多個專案,或者清除池,則如果指定的鍵不存在,則不得將其視為錯誤條件。後置條件相同(金鑰不存在,或者池為空),因此沒有錯誤條件。

6 介面

CacheItemInterface

CacheItemInterface定義快取系統內的項。每個Item物件必須與一個特定的鍵相關聯,該鍵可以根據實現系統進行設定,並且通常由Cache \ CacheItemPoolInterface物件傳遞。

Cache \ CacheItemInterface物件封裝了快取項的儲存和檢索。每個Cache \ CacheItemInterface都由Cache \ CacheItemPoolInterface物件生成,該物件負責任何所需的設定以及將物件與唯一Key相關聯。 Cache \ CacheItemInterface物件必須能夠儲存和檢索本文件“資料”部分中定義的任何型別的PHP值。

呼叫庫絕不能例項化Item物件。它們只能通過getItem()方法從Pool物件請求。呼叫庫不應該假設一個實現庫建立的項與另一個實現庫中的池相容。

<?php

namespace Psr\Cache;

/**
 * CacheItemInterface defines an interface for interacting with objects inside a cache.
 */
interface CacheItemInterface
{
    /**
     * Returns the key for the current cache item.
     *
     * The key is loaded by the Implementing Library, but should be available to
     * the higher level callers when needed.
     *
     * @return string
     *   The key string for this cache item.
     */
    public function getKey();

    /**
     * Retrieves the value of the item from the cache associated with this object's key.
     *
     * The value returned must be identical to the value originally stored by set().
     *
     * If isHit() returns false, this method MUST return null. Note that null
     * is a legitimate cached value, so the isHit() method SHOULD be used to
     * differentiate between "null value was found" and "no value was found."
     *
     * @return mixed
     *   The value corresponding to this cache item's key, or null if not found.
     */
    public function get();

    /**
     * Confirms if the cache item lookup resulted in a cache hit.
     *
     * Note: This method MUST NOT have a race condition between calling isHit()
     * and calling get().
     *
     * @return bool
     *   True if the request resulted in a cache hit. False otherwise.
     */
    public function isHit();

    /**
     * Sets the value represented by this cache item.
     *
     * The $value argument may be any item that can be serialized by PHP,
     * although the method of serialization is left up to the Implementing
     * Library.
     *
     * @param mixed $value
     *   The serializable value to be stored.
     *
     * @return static
     *   The invoked object.
     */
    public function set($value);

    /**
     * Sets the expiration time for this cache item.
     *
     * @param \DateTimeInterface|null $expiration
     *   The point in time after which the item MUST be considered expired.
     *   If null is passed explicitly, a default value MAY be used. If none is set,
     *   the value should be stored permanently or for as long as the
     *   implementation allows.
     *
     * @return static
     *   The called object.
     */
    public function expiresAt($expiration);

    /**
     * Sets the expiration time for this cache item.
     *
     * @param int|\DateInterval|null $time
     *   The period of time from the present after which the item MUST be considered
     *   expired. An integer parameter is understood to be the time in seconds until
     *   expiration. If null is passed explicitly, a default value MAY be used.
     *   If none is set, the value should be stored permanently or for as long as the
     *   implementation allows.
     *
     * @return static
     *   The called object.
     */
    public function expiresAfter($time);

}

CacheItemPoolInterface

Cache \ CacheItemPoolInterface的主要目的是接受來自呼叫庫的金鑰並返回關聯的Cache \ CacheItemInterface物件。它也是與整個快取集合互動的主要點。池的所有配置和初始化都由實現庫決定。 

<?php

namespace Psr\Cache;

/**
 * CacheItemPoolInterface generates CacheItemInterface objects.
 */
interface CacheItemPoolInterface
{
    /**
     * Returns a Cache Item representing the specified key.
     *
     * This method must always return a CacheItemInterface object, even in case of
     * a cache miss. It MUST NOT return null.
     *
     * @param string $key
     *   The key for which to return the corresponding Cache Item.
     *
     * @throws InvalidArgumentException
     *   If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
     *   MUST be thrown.
     *
     * @return CacheItemInterface
     *   The corresponding Cache Item.
     */
    public function getItem($key);

    /**
     * Returns a traversable set of cache items.
     *
     * @param string[] $keys
     *   An indexed array of keys of items to retrieve.
     *
     * @throws InvalidArgumentException
     *   If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
     *   MUST be thrown.
     *
     * @return array|\Traversable
     *   A traversable collection of Cache Items keyed by the cache keys of
     *   each item. A Cache item will be returned for each key, even if that
     *   key is not found. However, if no keys are specified then an empty
     *   traversable MUST be returned instead.
     */
    public function getItems(array $keys = array());

    /**
     * Confirms if the cache contains specified cache item.
     *
     * Note: This method MAY avoid retrieving the cached value for performance reasons.
     * This could result in a race condition with CacheItemInterface::get(). To avoid
     * such situation use CacheItemInterface::isHit() instead.
     *
     * @param string $key
     *   The key for which to check existence.
     *
     * @throws InvalidArgumentException
     *   If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
     *   MUST be thrown.
     *
     * @return bool
     *   True if item exists in the cache, false otherwise.
     */
    public function hasItem($key);

    /**
     * Deletes all items in the pool.
     *
     * @return bool
     *   True if the pool was successfully cleared. False if there was an error.
     */
    public function clear();

    /**
     * Removes the item from the pool.
     *
     * @param string $key
     *   The key to delete.
     *
     * @throws InvalidArgumentException
     *   If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
     *   MUST be thrown.
     *
     * @return bool
     *   True if the item was successfully removed. False if there was an error.
     */
    public function deleteItem($key);

    /**
     * Removes multiple items from the pool.
     *
     * @param string[] $keys
     *   An array of keys that should be removed from the pool.

     * @throws InvalidArgumentException
     *   If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
     *   MUST be thrown.
     *
     * @return bool
     *   True if the items were successfully removed. False if there was an error.
     */
    public function deleteItems(array $keys);

    /**
     * Persists a cache item immediately.
     *
     * @param CacheItemInterface $item
     *   The cache item to save.
     *
     * @return bool
     *   True if the item was successfully persisted. False if there was an error.
     */
    public function save(CacheItemInterface $item);

    /**
     * Sets a cache item to be persisted later.
     *
     * @param CacheItemInterface $item
     *   The cache item to save.
     *
     * @return bool
     *   False if the item could not be queued or if a commit was attempted and failed. True otherwise.
     */
    public function saveDeferred(CacheItemInterface $item);

    /**
     * Persists any deferred cache items.
     *
     * @return bool
     *   True if all not-yet-saved items were successfully saved or there were none. False otherwise.
     */
    public function commit();
}

CacheException

此異常介面旨在用於發生嚴重錯誤時,包括但不限於快取設定,如連線到快取伺服器或提供的無效憑據。

實現庫丟擲的任何異常都必須實現此介面。

<?php

namespace Psr\Cache;

/**
 * Exception interface for all exceptions thrown by an Implementing Library.
 */
interface CacheException
{
}

InvalidArgumentException

<?php

namespace Psr\Cache;

/**
 * Exception interface for invalid cache arguments.
 *
 * Any time an invalid argument is passed into a method it must throw an
 * exception class which implements Psr\Cache\InvalidArgumentException.
 */
interface InvalidArgumentException extends CacheException
{
}