Ubiquity不支持Redis/Memcached原生集成,需手动实现CacheInterface接口并继承CacheBase,重写get/set/delete/clear方法;必须在UBoot::run()前调用CacheManager::setInstance()替换默认缓存实例,否则无效。

为什么不能直接 new Redis() 或 new Memcached() 就完事
因为业务逻辑里一旦硬编码 new Redis(),后续想切到 Memcached 就得全局搜替换、改条件判断、重测所有缓存路径——这不是扩展,是埋雷。适配器模式要解决的,就是让上层代码完全不知道底层用的是哪个驱动,只认一个接口。
必须定义 CacheInterface 并统一方法签名
Ubiquity 的 CacheInterface 已经规定了 get、set、delete、clear 四个方法,但它的默认实现(FileCache)和你写的 RedisCache / MemcachedCache 必须严格对齐参数和返回值语义:
-
set($key, $value, $duration = 0):$duration 为 0 表示永不过期,Redis 要用set,Memcached 要用set(不是setex),别写反 -
get($key)返回null表示未命中,不能抛异常或返回false(否则上层判空逻辑全崩) - 所有 key 必须加统一前缀(如
ubq:),否则 Redis 和 Memcached 实例混用时会互相污染
RedisCache 和 MemcachedCache 的关键差异点
两者看似相似,但初始化、序列化、过期处理细节完全不同:
-
RedisCache构造时用$redis->connect(),并设\Redis::OPT_PREFIX;MemcachedCache构造时用$memcached->addServer(),前缀得自己拼在$key前 -
RedisCache::get()必须用@unserialize()容错,因为$redis->get()可能返回false或损坏字符串;MemcachedCache::get()直接返回原值,但需检查$memcached->getResultCode() === \Memcached::RES_SUCCESS -
RedisCache::set()对$duration > 0调用setex(),等于 0 时调用set();MemcachedCache::set()统一走set($key, $value, $duration),它把 0 当永久
如何在 Ubiquity 中真正启用自定义驱动
光写好类没用,Ubiquity 不会自动扫描或注册。必须在 UBoot::run() 之前手动替换单例:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
立即学习“PHP免费学习笔记(深入)”;
$redisConfig = ['host' => '127.0.0.1', 'port' => 6379, 'prefix' => 'ubq:'];
$cache = new RedisCache($redisConfig);
\Ubiquity\cache\CacheManager::setInstance($cache);
UBoot::run('app', false);
常见错误是把这个调用放在路由或控制器里——太晚了,框架启动时已初始化默认缓存实例,再换也无效。另外,CacheManager::setDriver('redis') 这种写法会直接报 "Driver not found",因为 Ubiquity v4+ 根本不识别该字符串,它只认你传进去的实例对象。
最易被忽略的是连接复用和错误静默:Redis/Memcached 实例必须是长连接且全局复用,不能每次 get 都新建;所有网络失败、序列化失败、空值返回都得兜住,否则一个缓存故障就能拖垮整个请求。


















