Yii没有内置“标签缓存”,实际使用的是片段缓存,需配对调用beginCache()和endCache();漏掉后者会导致页面截断,缓存键默认基于视图路径生成,支持dependency自动失效,duration为0时依赖缓存组件TTL。

Yii 的“标签缓存”并不存在——框架里没有叫 tagCache 或类似机制的内置功能。你真正想用的,是片段缓存(fragment caching),靠 beginCache() 和 endCache() 实现。
片段缓存必须配对使用 beginCache() 和 endCache()
漏掉 endCache() 是最常见也最隐蔽的错误:后续所有视图输出(包括 </body>、</html>)都会被吞掉,页面直接截断,浏览器源码里看不到结尾标签。这不是报错,而是静默失败。
-
beginCache()必须在 PHP 代码块中调用,不能写在纯 HTML 区域里 - 两个函数必须在同一视图文件中成对出现,不能跨
include或render()调用 - 如果嵌套使用(比如外层列表 + 内层单条详情),每个
beginCache()都要对应一个endCache()
beginCache() 的关键参数怎么选
缓存是否生效、何时失效,全看这几个参数:
-
duration:整数秒,默认 0(不缓存)。设为3600表示 1 小时后过期 -
dependency:传new \yii\caching\DbDependency(['sql' => 'SELECT MAX(updated_at) FROM post'])这类依赖对象,数据库变更时自动让缓存失效 -
variations:数组,比如['language' => \Yii::$app->language],用于多语言场景下区分缓存版本 -
enabled:布尔值,可动态开关,调试时设为false能快速验证逻辑是否被绕过
注意:duration 和 dependency 不是互斥的,可以同时设置——缓存会在任一条件满足时失效(先到为准)。
缓存键生成规则和手动干预
Yii 默认用视图路径 + 参数 + 上下文生成缓存键,但容易踩坑:
- 如果视图里用了
$this->context->id或\Yii::$app->user->id这类动态值,但没显式写进variations,会导致不同用户看到相同缓存内容 - 想强制刷新某段缓存?调用
\Yii::$app->cache->delete('your-custom-key')没用——得先知道 Yii 实际生成的键名;更稳妥的做法是改variations中某个值(比如加个时间戳后缀)或更新dependency查询结果 - 调试时可在
beginCache()后加echo \Yii::$app->cache->buildKey(['my', 'cache', 'key']);看真实键名(仅开发环境)
性能与并发要注意什么
片段缓存本身不锁文件或数据库,但底层缓存组件(如 FileCache)在写入时会用 LOCK_EX 排它锁:
- 高并发下多个请求同时触发缓存生成,可能造成重复计算(即“缓存击穿”),Yii 不自带原子写入保护
- 避免在
beginCache()区块内做耗时 DB 查询或 API 调用——缓存目的是省掉这些,不是包住它们再执行一遍 - 如果依赖项(
dependency)查询本身慢,反而拖累首屏速度,建议把依赖 SQL 提前优化或加索引
真正难处理的是缓存粒度和依赖更新时机的平衡:太粗(整个列表缓存)容易 stale,太细(每行都缓存)又增加键管理成本。别指望靠加 duration 值来掩盖依赖设计缺陷。


















