在 Discuz 插件开发中,前端数据缓存机制主要通过 **分层缓存策略** 实现,具体流程如下:
---
### 一、缓存类型与调用逻辑
1. **内存级缓存(核心)**
- 使用 `C::cache('插件标识', '缓存键')` 方法直接操作内存缓存(Memcached/Redis/APC)
- 数据以键值对存储,响应速度在毫秒级
- 示例代码:
- // 读取缓存
- $data = C::cache('plugin_example', 'hot_topics');
- if(!$data){
- // 无缓存则从DB查询
- $data = C::t('plugin_example_table')->fetch_all();
- // 写入缓存并设置3600秒过期
- C::cache('plugin_example', 'hot_topics', $data, 3600);
- }
复制代码
2. **数据库级缓存(辅助)**
- 通过 `pluginvar` 表存储配置型数据(后台保存时自动生成)
- 使用 `$_G['cache']['plugin']['插件标识']` 全局变量调用
- 适用于低频修改、高频读取的数据(如插件配置参数)
---
### 二、前端调用流程
1. **模板层调用**
- 通过 `<!--{eval $data = C::cache('plugin_example','data');}-->` 嵌入模板
- 或使用 `{eval output_cache('plugin/data_block', 600)}` 实现区块级缓存
2. **钩子(Hook)缓存**
- 在 `hook.class.php` 中通过 `_checkcaches()` 方法验证缓存有效性
- 当检测到数据变更时自动刷新关联缓存节点
3. **AJAX 接口缓存**
- 在 `plugin.php` 控制器中使用 `setglobal('cachetime', 300)` 设置接口缓存时间
- 配合 `$_G['gzipcompress']` 实现压缩传输
---
### 三、缓存存储位置
| 缓存类型 | 存储介质 | 生命周期 |
|----------------|---------------------------|--------------------------|
| 内存缓存 | Redis/Memcached | 可设置TTL(建议≤86400) |
| 模板编译缓存 | ./data/template/ | 模板修改后自动重建 |
| 数据库配置缓存 | pre_common_plugin | 插件启用/停用时刷新 |
| 区块输出缓存 | ./data/cache/cache_xxx.php| 依赖设定的缓存时间 |
---
### 四、优化建议
1. **分级存储策略**
- 热点数据优先存内存 → 次热数据存文件 → 冷数据直接查库
2. **批量更新机制**
- // 使用批量更新减少缓存穿透
- C::t('plugin_example_table')->update_batch($updateData);
- C::cache('plugin_example', '*', null); // 清空插件所有缓存
复制代码
3. **缓存雪崩防护**
- $ttl = 600 + mt_rand(0,300); // 随机过期时间分散重建压力
复制代码
如需深入理解缓存运作机制,建议参考《Discuz! 插件开发手册》中的 **[缓存管理模块](https://addon.dismall.com/library/)** 章节,该文档详细说明了缓存生命周期管理和性能调优方法。
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。 |