功能
- 支持缓存渲染后数据
- 支持指定缓存过期时间(默认10分钟)
- header头输出缓存命中状态、缓存Key及过期时间
- 支持定义tag,方便集中删除
/app/Http/Middleware/CacheResponse.php
<?php
namespace App\Http\Middleware;
use Carbon\Carbon;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
/**
* Response缓存中间件
*
*/
class CacheResponse
{
/**
* @var \Illuminate\Http\Request
*/
protected $request;
/**
* @var \Closure
*/
protected $next;
/**
* 缓存分钟
*
* @var int|null
*/
protected $minutes;
/**
* 缓存数据
*
* @var array
*/
protected $responseCache;
/**
* 缓存命中状态,1为命中,0为未命中
*
* @var int
*/
protected $cacheHit = 1;
protected $tag = 'routeCache';
/**
* 缓存Key
*
* @var string
*/
protected $cacheKey;
/**
* Handle an incoming request
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param int|null $minutes
* @param string|null $tag
*
* @return mixed
*/
public function handle($request, Closure $next, $minutes = null, $tag = null)
{
$this->prepare($request, $next, $minutes, $tag);
$this->responseCache();
$response = response($this->responseCache['content']);
return $this->addHeaders($response);
}
/**
* 预备
*
* @return mixed
*/
protected function prepare($request, Closure $next, $minutes = null, $tag = null)
{
$this->request = $request;
$this->next = $next;
$this->tag = $tag ?: 'routeCache';
// 初始化值
$this->cacheKey = $this->resolveKey();
$this->minutes = $this->resolveMinutes($minutes);
}
/**
* 生成或读取Response-Cache
*
* @return array
*/
protected function responseCache()
{
$this->responseCache = cache()->tags(array_merge(['routeCache'], [$this->tag]))->remember(
$this->cacheKey,
$this->minutes * 60,
function () {
$this->cacheMissed();
$response = ($this->next)($this->request);
return $this->resolveResponseCache($response) + [
'cacheExpireAt' => Carbon::now()->addMinutes($this->minutes)->format('Y-m-d H:i:s T'),
];
}
);
return $this->responseCache;
}
/**
* 确定需要缓存Response的数据
*
* @param \Illuminate\Http\Response $response
*
* @return array
*/
protected function resolveResponseCache($response)
{
return [
'content' => $response->getContent(),
];
}
/**
* 追加Headers
*
* @param mixed
*/
protected function addHeaders($response)
{
$response->headers->add(
$this->getHeaders()
);
return $response;
}
/**
* 返回Headers
*
* @return array
*/
protected function getHeaders()
{
$headers = [
'X-Cache' => $this->cacheHit ? 'Hit from cache' : 'Missed',
'X-Cache-Key' => $this->cacheKey,
'X-Cache-Expires' => $this->responseCache['cacheExpireAt'],
];
return $headers;
}
/**
* 根据请求获取指定的Key
*
* @return string
*/
protected function resolveKey()
{
return md5($this->request->url().Arr::query($this->request->input()));
}
/**
* 获取缓存的分钟
*
* @param int|null $minutes
*
* @return int
*/
protected function resolveMinutes($minutes = null)
{
return is_null($minutes)
? $this->getDefaultMinutes()
: max($this->getDefaultMinutes(), intval($minutes));
}
/**
* 返回默认的缓存时间(分钟)
*
* @return int
*/
protected function getDefaultMinutes()
{
return 10;
}
/**
* 缓存未命中
*
* @return mixed
*/
protected function cacheMissed()
{
$this->cacheHit = 0;
}
}
配置
\app\Http\Kernel.php
文件中$routeMiddleware
增加:
<?php
'cacheResponse' => \app\Http\Middleware\CacheResponse::class,
// cacheResponse 命名随意,你开心就好
使用
<?php
Route::get('/', function () {
return view('welcome');
})->middleware('cacheResponse'); //名称和上面保持一致
Route::get('/', function () {
return view('welcome');
})->middleware('cacheResponse:20'); // 指定缓存时间20分钟
Route::get('/', function () {
return view('welcome');
})->middleware('cacheResponse:20,tag'); // 指定缓存标签'tag'
删除
<?php
cache()->tags(['routeCache'])->flush(); //删除全部路由缓存
cache()->tags(['tag'])->flush(); //删除标签tag的路由缓存
网友评论