php artisan plugin:install SerenityNow.Cacheroute
假如有个 blog
列表页面 ,且这个页面只是展示作用,没有和前台交互,这就有必要为这个页面添加为缓存,设为10分钟。
我们知道php
有个 microtime(true)
函数,记录的是程序运行到某一时间点所用的时间,因此在octobercms
启动前,放置一个,在后置中间件也放置一个,两个之差为程序所运行的时间。
在 bootsrrap/app.php 中
define('OCTOBER_START', microtime(true)); //放置
$app = new October\Rain\Foundation\Application(
realpath(__DIR__.'/../')
);
然后替换文件
//把以下内容替换文件plugins/serenitynow/cacheroute/classes/RouteCacheMiddleware.php
<?php
namespace SerenityNow\Cacheroute\Classes;
use Illuminate\Http\Request as LaravelRequest;
use SerenityNow\Cacheroute\Models\CacheRoute;
use Closure;
class RouteCacheMiddleware
{
public function handle(LaravelRequest $request, Closure $next)
{
//bail if table does not exist or
//route not in the list of routes to be cached
$hasTable = \Schema::hasTable('serenitynow_cacheroute_routes');
$cacheRow = $this->shouldBeCached($request);
$ajaxRequest = $request->ajax();
if (!$hasTable || !$cacheRow || $ajaxRequest) {
$response=$next($request);
$response->headers->set('X-Elapsed-Time', microtime(true) - OCTOBER_START);
return $response;
}
return $this->cacheResponse($request, $next, $cacheRow['cache_ttl']);
}
/**
* @param LaravelRequest $request
* @param Closure $next
* @param $ttl
* @return mixed
*/
protected function cacheResponse(LaravelRequest $request, Closure $next, $ttl)
{
$cacheKey = $this->getCacheKey($request->url());
if (\Cache::has($cacheKey)) {
return \Response::make($this->getCachedContent($cacheKey, $request, \Cache::get($cacheKey)), 200,['X-Elapsed-Time-Cache'=>microtime(true) - OCTOBER_START]);
}
$response = $next($request);
$response->headers->set('X-Elapsed-Time', microtime(true) - OCTOBER_START);
\Cache::put($cacheKey, $response->getContent(), $ttl);
return $response;
}
/**
* add instrumentation to help with debug. Adding ?debug
* to a cached url will precede the content with "CACHED"
*
* @param $cacheKey
* @param $request
* @param $content
* @return string
*/
protected function getCachedContent($cacheKey, $request, $content)
{
$isDebugRequest = $request->exists('debug') || $request->exists('cache-info');
if ($isDebugRequest) {
return $content.'
<div class="cache-notice" style="display: block; position: fixed; width: 50%; background: #fff; padding: 20px 30px 25px; left: 50%; border: 1px solid #aaa; margin-left: calc(-50% / 2); bottom: 10%; z-index: 500; box-shadow: 0 0 20px rgba(0,0,0,0.2); font-size: 16px; font-size: 1.6rem;">
<div class="title" style="margin: -20px -30px 10px; background: #999; color: #fff; padding: 10px 30px; text-align: center;">CACHED CONTENT</div>
<span class="cache_key" style="display: inline-block; width: 100%; background: #fff; padding: 10px 10px 10px 0; margin-bottom: -10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
<span class="title" style="float: left; width:45px; color: #000; font-weight: bold; line-height: 30px;">URL: </span>
<input readonly class="value" style="float: left; width: calc(100% - 45px); border:1px solid #000; color: red; padding: 5px 7px; height: 30px; background: #eee" type="text" value="'.$request->url().'">
</span>
<span class="cache_key" style="display: inline-block; width: 100%; background: #fff; color: red; padding: 10px 10px 10px 0; margin-bottom: -10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
<span class="title" style="float: left; width:45px; color: #000; font-weight: bold; line-height: 30px;">KEY: </span>
<input readonly class="value" style="float: left; width: calc(100% - 45px); border:1px solid #000; color: red; padding: 5px 7px; height: 30px; background: #eee" type="text" value="'.$cacheKey.'">
</span>
<hr style="border:none;">
<a href="'.$request->url().'" class="cancel" style="float: left; background: #aaa; color: #fff; padding: 10px 15px; margin-top: 20px; text-decoration: none;">Cancel</a>
<a href="?cache-clear" class="alert alert-info" style="float: right; background: #1991d1; color: #fff; padding: 10px 15px; margin-top: 20px; text-decoration: none;">Clear this now</a>
</div>';
}
if ($request->exists('cache-clear')) {
\Cache::forget($cacheKey);
return \Redirect::to($request->url());
}
return $content;
}
//generate a cache key based on the url
/**
* @param $url
* @return string
*/
protected function getCacheKey($url)
{
return 'SerenityNow.Cacheroute.' . str_slug($url);
}
/**
* @param $request
* @return bool
*/
protected function shouldBeCached($request)
{
$cacheRouteRows = \Cache::remember('SerenityNow.Cacheroute.AllCachedRoutes',
\Config::get('cms.urlCacheTtl'),
function () {
return CacheRoute::orderBy('sort_order')->get()->toArray();
}
);
info($request->url());
foreach ($cacheRouteRows as $cacheRow) {
if (count($cacheRow) && $request->is($cacheRow['route_pattern'])) {
return $cacheRow;
}
}
return false;
}
}
只用观察一下header中的X-Elapsed-Time
和X-Elapsed-Time-Cache
X-Elapsed-Time
无缓存的运行时间X-Elapsed-Time-Cache
缓存生效后的运行时间1 第一次进入页面
可以看到无缓存时的运行时间为
X-Elapsed-Time: 0.39185500144958
2 再刷新一次页面
有缓存时的运行时间为
X-Elapsed-Time-Cache: 0.051207065582275
0.3918/0.0512=7.6 提升了将近8倍 还是挺不错的
一般来说缓存的适用场景是页面静态化,这个方法是在路由的基础上增加缓存的,对于不常变动的页面是个很好的方法。,但对于动态页面来说,在路由层面加缓存,就不适合了,这时可以在数据的基础上加缓存,监听数据的变动,之后去更新缓存
如果您想直观的观看下缓存的效果,可以在链接访问 https://jc91715.top/blog?debug 可以清除下缓存观看页面的执行效果
Posted in octobercms, php, 后端 on Apr 17, 2018
请登录 登录 评论!