2023-12-18 14:45:11
浏览数 (3)
- 我们不管写页面还是写接口的时候,经常会用到一个功能。
- 通常一个请求过来,我们从数据库中查询出来,然后数据转换处理完成之后返回
- 但是有一些页面,比如首页或者某个接口数据不是经常改动的,请求多了,会造成影响
- 所以,我们可以第一次请求处理完成输出之前,把内容缓存到
Redis
之类的存储 - 下次再请求这个,先从
Redis
读取数据,没过期直接返回不需要处理。 - 如果缓存过期,那么重复 [3, 4]
代码语言:javascript
复制<?php
namespace AppMiddleware;
use NyholmPsr7Stream;
use PsrHttpMessageResponseInterface;
use PsrHttpMessageServerRequestInterface;
use PsrHttpServerRequestHandlerInterface;
class PageCacheMiddleware
{
public function __invoke(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$paths = [
'/' => [],
'/categories' => [],
'/articles' => [],
];
$requestPath = $request->getUri()->getPath();
// 不需要缓存的路由
if (
(strtoupper($request->getMethod()) !== 'GET') ||
! array_key_exists($path, $configs)
) {
return $handler->handle($request);
}
// 可能,你的 cacheKey 还需要加一些参数辨别,例如 page=1
$requestParameters = $request->getQueryParams();
$cacheKey = base64_encode($requestPath . json_encode($requestParameters));
// 这里,你可以从缓存中获取,这里为了演示简单,直接通过文件读写来达到缓存的效果
if (file_exists($cacheKey)) {
list($cacheResponse, $cacheContent) = unserialize(file_get_contents($cacheKey));
if ($cacheResponse instanceof ResponseInterface) {
$newResponse = $cacheResponse->withBody(Stream::create($cacheContent));
return $newResponse;
}
}
$response = $handler->handle($request);
// 这里,我们把这个 Response 对象缓存起来,因为我们需要响应头等信息,
// 还缓存了 body,这里最为重要,slim4 的 body 使用 php_temp 流,
// 而 PHP 中说到,流是不能序列化的。所以我们也缓存一个内容
file_put_contents($cacheKey, serialize([$response, (string)$response->getBody()]));
return $response;
}
}