ميكيه/psr7-cache

此软件包已被废弃,不再维护。没有建议替代软件包。

PSR-7 HTTP 消息的缓存和条件请求助手

0.5 2016-04-15 16:31 UTC

This package is auto-updated.

Last update: 2021-05-24 01:33:08 UTC


README

Build Status Code Coverage Scrutinizer Code Quality

此库提供了一种简单的方法来为 PSR-7 HTTP 消息实现添加与缓存相关的头信息,或者从 PSR-7 消息中提取缓存和条件请求信息(例如,如果响应可缓存)。它还提供了一个 Cache-Control 值对象,以提供用于操作 Cache-Control 头的对象化接口。

安装

使用 Composer 安装此库

$ composer require micheh/psr7-cache

快速入门

要启用 HTTP 响应的缓存,创建一个 CacheUtil 实例,调用 withCache 方法并提供您的 PSR-7 响应。

/** @var \Psr\Http\Message\ResponseInterface $response */

$util = new \Micheh\Cache\CacheUtil();
$response = $util->withCache($response);

这将向您的响应添加头信息 Cache-Control: private, max-age=600。带有此头信息的响应将只由发送请求的客户端缓存,并缓存 600 秒(10 分钟)。在此期间,客户端应使用缓存的响应,而不应向应用程序发出新请求。

缓存验证器

应用程序还应向响应中添加缓存验证器:一个 ETag 头信息(如果您知道资源最后修改的时间,还可以添加 Last-Modified 头信息)。这样,客户端也会在请求中包含 ETagLast-Modified 信息,应用程序可以检查客户端是否仍然具有当前状态。

/** @var \Psr\Http\Message\ResponseInterface $response */

$util = new \Micheh\Cache\CacheUtil();
$response = $util->withCache($response);
$response = $util->withETag($response, 'my-etag');
$response = $util->withLastModified($response, new \DateTime());

重新验证响应

为了确定客户端是否仍然具有页面的当前副本并且响应未被修改,您可以使用 isNotModified 方法。只需将缓存头信息添加到响应中,然后使用请求和响应调用该方法。该方法将自动比较请求的 If-None-Match 头信息与响应的 ETag 头信息(以及/或请求的 If-Modified-Since 头信息与响应的 Last-Modified 头信息,如果可用)。如果响应未被修改,则返回带有缓存头信息和状态代码 304(未修改)的空响应。这将指示客户端使用之前请求的缓存副本,从而节省 CPU/内存使用和带宽。因此,为了提高性能,重要的是将 isNotModified 调用之前的代码保持尽可能轻量。不要在此方法之前创建完整的响应。

/** @var \Psr\Http\Message\RequestInterface $request */
/** @var \Psr\Http\Message\ResponseInterface $response */

$util = new \Micheh\Cache\CacheUtil();
$response = $util->withCache($response);
$response = $util->withETag($response, 'my-etag');
$response = $util->withLastModified($response, new \DateTime());

if ($util->isNotModified($request, $response)) {
    return $response->withStatus(304);
}

// create the body of the response

带有不安全方法的条件请求

虽然上述描述的过程通常是可选的,并且适用于安全方法(GET和HEAD),但也可能强制要求客户端具有当前资源状态。这对于不安全的方法(例如POST、PUT、PATCH或DELETE)很有用,因为它可以防止更新丢失(例如,如果另一个客户端在您的请求之前更新了资源)。使用hasStateValidator方法最初检查请求是否包含适当的头信息(对于ETag使用If-Match,对于Last-Modified日期使用If-Unmodified-Since)是个好主意。如果请求不包含此信息,则中止执行并返回状态码428(必需的条件)或状态码403(禁止)。

/** @var \Psr\Http\Message\RequestInterface $request */

$util = new \Micheh\Cache\CacheUtil();
if (!$util->hasStateValidator($request)) {
    return $response->withStatus(428);
}

如果请求中包含了状态验证器,您可以使用hasCurrentState方法检查请求是否具有当前资源状态,而不是过时的版本。如果请求有一个过时的资源状态(另一个ETag或更旧的Last-Modified日期),则中止执行并返回状态码412(条件失败)。否则,您可以继续处理请求并更新/删除资源。一旦资源更新,最好在响应中包含更新的ETag(如果可用,还可以包含Last-Modified日期)。

/** @var \Psr\Http\Message\RequestInterface $request */
/** @var \Psr\Http\Message\ResponseInterface $response */

$util = new \Micheh\Cache\CacheUtil();
if (!$util->hasStateValidator($request)) {
    return $response->withStatus(428);
}

$eTag = 'my-etag'
$lastModified = new \DateTime();
if (!$util->hasCurrentState($request, $eTag, $lastModified)) {
    return $response->withStatus(412);
}

// process the request

可用的辅助方法

方法 描述(更多信息请参阅phpDoc)
withCache 添加Cache-Control头的便利方法,允许缓存
withCachePrevention 防止缓存的便利方法
withExpires 从一个时间戳、字符串或DateTime添加Expires
withRelativeExpires 添加具有特定生命周期的Expires
withETag 添加ETag
withLastModified 从一个时间戳、字符串或DateTime添加Last-Modified
withCacheControl 从字符串或值对象添加Cache-Control
hasStateValidator 检查是否可以确定资源状态
hasCurrentState 检查请求是否具有当前资源状态
isNotModified 检查响应是否未修改
isCacheable 检查响应是否可由公共缓存缓存
isFresh 检查响应是否新鲜(年龄小于生命周期)
getLifetime 返回响应的寿命(应缓存多久)
getAge 返回响应的年龄(在缓存中存在了多久)

参考

许可

此存档中的文件受BSD-3-Clause许可的许可。您可以在LICENSE.md中找到此许可证的副本。