缓存使用方法
基本操作
获取缓存 get()
php
use Viswoole\Cache\Facade\Cache;
// 获取缓存值
$value = Cache::get('key');
// 带默认值
$value = Cache::get('key', 'default');
// 获取不存在的键返回默认值
$name = Cache::get('user:name', '匿名用户');设置缓存 set()
php
// 基本写入,使用驱动默认过期时间
Cache::set('key', 'value');
// 指定过期时间(秒)
Cache::set('key', 'value', 3600); // 1小时后过期
// 使用 DateTime 对象指定过期时间
$expireAt = new DateTime('+1 hour');
Cache::set('key', 'value', $expireAt);
// NX 模式:仅当键不存在时写入(防覆盖)
Cache::set('lock:resource', 'locked', 300, true);判断缓存存在 has()
php
if (Cache::has('user:session')) {
// 会话缓存存在
}删除缓存 delete()
php
// 删除单个缓存
Cache::delete('key');
// 批量删除
Cache::delete(['key1', 'key2', 'key3']);清除所有缓存 clear()
php
// 清除当前驱动下的所有缓存
Cache::clear();数值操作
自增 increment/inc()
php
// 设置初始计数器
Cache::set('views', 100);
// 自增(默认步长为 1)
Cache::inc('views'); // 101
Cache::inc('views', 10); // 111
// 注意:值必须为数值类型,否则抛出异常自减 decrement/dec()
php
// 自减
Cache::dec('stock', 1); // 库存减 1高级用法
获取并删除 pull()
php
// 获取缓存值并立即删除(原子操作)
$data = Cache::pull('temporary:data');获取剩余有效期 ttl()
php
// 获取缓存剩余有效时间(秒)
$ttl = Cache::ttl('key');
if ($ttl === false) {
// 缓存不存在或已过期
} elseif ($ttl === -1) {
// 缓存长期有效(未设置过期时间)
} else {
// 返回剩余秒数
}竞争锁 lock()
php
try {
// 获取锁
$lockId = Cache::lock('order:create', 10, false, 5, 0.2);
// 参数说明:
// 场景标识, 过期时间(秒), 是否自动解锁, 重试次数, 重试间隔(秒)
// 执行业务逻辑...
createOrder();
// 手动释放锁
Cache::unlock($lockId);
} catch (\Viswoole\Cache\Exception\CacheErrorException $e) {
// 获取锁失败
}数组集合操作
php
// 向数组集合追加元素
Cache::sAddArray('tags', ['php', 'swoole']);
Cache::sAddArray('tags', 'redis');
// 获取数组集合所有元素
$tags = Cache::getArray('tags');
// 返回: ['php', 'swoole', 'redis']
// 从数组集合移除元素
Cache::sRemoveArray('tags', ['php']);多缓存商店
php
// 切换到指定缓存商店
Cache::store('redis')->set('key', 'value', 3600);
$value = Cache::store('redis')->get('key');
// 添加自定义商店
Cache::addStore('custom', new MyCustomDriver());
// 判断商店是否存在
if (Cache::hasStore('custom')) {
// 商店已注册
}
// 获取实际缓存标识(含前缀)
$realKey = Cache::getCacheKey('key');序列化定制
php
// 自定义序列化方法(如使用 JSON 替代 PHP serialize)
Cache::setSerialize(
fn($data) => json_encode($data),
fn($data) => json_decode($data, true)
);最佳实践
1. 缓存热点数据查询
php
public function getUser(int $id): array
{
$cacheKey = "user:{$id}";
// get() 不支持闭包回调,需手动判断 has() 后再 set()
if (Cache::has($cacheKey)) {
return Cache::get($cacheKey);
}
$user = User::find($id);
$data = $user->toArray();
Cache::set($cacheKey, $data, 3600);
return $data;
}注意:
get()方法的第二个参数是默认值(mixed $default),不支持闭包回调。若传入闭包且缓存不存在,将直接返回闭包对象本身。如需实现"不存在时自动填充"的逻辑,请手动判断has()后再set()。
2. 缓存穿透防护
php
public function getData(string $key): mixed
{
$cacheKey = "data:" . md5($key);
if (Cache::has($cacheKey)) {
return Cache::get($cacheKey);
}
$data = $this->fetchFromDatabase($key);
// 即使数据为空也缓存短时间,防止穿透
$ttl = empty($data) ? 60 : 3600;
Cache::set($cacheKey, $data, $ttl);
return $data;
}3. 分布式锁控制并发
php
public function placeOrder(array $orderData): bool
{
$lockId = Cache::lock("order:{$orderData['user_id']}", 5, true);
try {
// 检查是否重复下单
if (Cache::has("pending:{$orderData['user_id']}")) {
return false;
}
// 标记正在处理
Cache::set("pending:{$orderData['user_id']}", true, 10);
// 创建订单...
return $this->createOrder($orderData);
} finally {
Cache::unlock($lockId);
}
}