- there is a feature we often use when writing pages or interfaces.
- Usually a request comes, we query it from the database, and then return it after the data conversion processing is completed
- However, some pages, such as the home page or the data of an interface, are not changed frequently
- Therefore, we can cache the contents to a store like ‘Redis’ before the first request processing completes the output
- The next time you request this, read the data from ‘Redis’ first, and return it directly without processing.
- If the cache expires, repeat [3, 4]
<?php
namespace App\Middleware;
use Nyholm\Psr7\Stream;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class PageCacheMiddleware
{
public function __invoke(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$paths = [
'/' => [],
'/categories' => [],
'/articles' => [],
];
$requestPath = $request->getUri()->getPath();
// 不需要缓存的路由
if (! isset($paths[$requestPath])) {
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;
}
}
2 Likes
Hi,
Can you show me an real example of this class?
Thank you!
I think there’s a little typo
if (! isset($paths[$requestPath])) {
return $handler->handle($request);
}
This shoud be
if (isset($paths[$requestPath])) {
return $handler->handle($request);
}