ThinkPHP 5.0 静态缓存默认不支持带参数搜索页,因按URL缓存且忽略GET参数;推荐用Route::cache()并指定params实现精准缓存,或自定义html_cache_rules拼接参数,再辅以Db::cache()双重加速。

ThinkPHP 5.0 的“静态缓存”(即 HTML 缓存)默认不适用于带参数的搜索页,因为它按完整 URL 或路由规则生成缓存文件,而搜索请求通常包含动态查询参数(如 ?q=xxx&page=2),若未显式处理这些参数,系统可能将所有搜索请求映射到同一个缓存文件,导致结果错乱或始终返回首次缓存的内容。
明确区分:静态缓存 ≠ 请求缓存 ≠ 查询缓存
先理清三个概念,避免配置错位:
-
页面/静态缓存(html_cache):将整个渲染后的 HTML 输出保存为 .shtml 文件,依赖
html_cache_rules规则匹配 URL;对 GET 参数默认不敏感,需手动参与规则构造。 - 请求缓存(Route::cache()):在路由层拦截,自动基于请求路径 + 序列化参数生成唯一缓存键,天然支持搜索类动态 URL,推荐用于搜索页。
- 查询缓存(Db::cache()):只缓存数据库查询结果,不影响模板渲染逻辑,适合配合搜索逻辑做二级加速。
用请求缓存实现搜索结果缓存(推荐方案)
这是最直接、最可靠的方式。在 route/route.php 中为搜索路由添加缓存配置:
Route::get('search', 'index/search/index')
->cache([
'expire' => 1800, // 缓存30分钟
'params' => ['q', 'page', 'sort'], // 明确指定参与缓存键的参数
'prefix' => 'search_'
]);
说明:
立即学习“PHP免费学习笔记(深入)”;
-
params是关键——它确保?q=手机&page=1和?q=手机&page=2生成不同缓存文件,避免翻页错乱; - 未列入
params的参数(如utm_source)会被忽略,防止缓存碎片; - 若搜索页需实时性(如后台刚发布新内容),可加
callback参数校验数据更新时间,返回false则跳过缓存。
若坚持用页面静态缓存(html_cache),必须自定义规则
在 application/config.php 的 html_cache_rules 中,不能用通配符 '*' 简单覆盖,而要显式拼接查询参数:
'html_cache_rules' => [
'search' => [
'{:module}/{:controller}/{:action}_{$_GET.q|md5}_{$_GET.page|default=1}',
1800,
['get' => ['q', 'page', 'sort']]
],
],
注意点:
- 使用
{$_GET.xxx}语法读取实际 GET 参数,|md5防止特殊字符破坏文件名; -
|default=1为缺失参数提供默认值,保证 URL 无page时也能命中缓存; -
['get' => [...]]是可选但建议的附加规则,用于限定仅当这些参数存在时才启用缓存; - 务必关闭
app_debug,否则静态缓存不生效。
搭配数据库查询缓存提升响应速度
在搜索控制器中,对高频查询进一步缓存结果:
public function index()
{
$q = input('q/s', '');
$page = input('page/d', 1);
$list = Db::name('article')
->where('title', 'like', "%{$q}%")
->cache("search_{$q}_{$page}", 1800) // 使用语义化 key
->paginate(10);
$this->assign('list', $list);
return $this->fetch();
}
这样即使请求缓存失效,数据库层仍有机会复用结果,形成双重保障。



















