目 录CONTENT

文章目录

🍛ThinkPHP8中使用redis缓存

柯基
2025-11-09 / 0 评论 / 0 点赞 / 14 阅读 / 1,585 字

实现了使用redis缓存自增版本、指定缓存版本号

1. 在.env中添加以下配置

# Redis
REDIS_HOST = 127.0.0.1
REDIS_PORT = 6379
REDIS_PASS = password
REDIS_CACHE_SELECT = 2

2. 修改缓存配置文件

config/cache.php

<?php

// +----------------------------------------------------------------------
// | 缓存设置
// +----------------------------------------------------------------------

return [
    // 默认缓存驱动
    'default' => 'redis',

    // 缓存连接方式配置
    'stores'  => [
        'file' => [
            // 驱动方式
            'type'       => 'File',
            // 缓存保存目录
            'path'       => '',
            // 缓存前缀
            'prefix'     => '',
            // 缓存有效期 0表示永久缓存
            'expire'     => 0,
            // 缓存标签前缀
            'tag_prefix' => 'tag:',
            // 序列化机制 例如 ['serialize', 'unserialize']
            'serialize'  => [],
        ],
        // 更多的缓存连接
        'redis' => [
            'type' => 'redis',
            // Redis 主机
            'host' => env('REDIS_HOST', '127.0.0.1'),
            // Redis 端口
            'port' => env('REDIS_PORT', 6379),
            // Redis 密码
            'password' => env('REDIS_PASS', ''),
            // 库
            'select' => env('REDIS_CACHE_SELECT', 2),
            // 缓存前缀
            'prefix' => '',
            // 缓存有效期 0表示永久缓存
            'expire' => 0,
//            // 缓存标签前缀
//            'tag_prefix' => 'tag:',
//            // 是否使用连接池
//            'use_pool' => true,
//            // 连接池的连接标识
//            'pool' => 'default',
        ],
    ],
];

3.缓存相关常量配置

<?php
declare (strict_types=1);

namespace app\common\enum;

class CacheEnum
{
    // 版本号前缀
    const CACHE_VERSION_PREFIX = 'cache_version_v1001';
    // 版本号初始值
    const DEFAULT_VERSION = 1001;
    // 缓存键前缀
    const CACHE_PREFIX = 'data_cache';

    /** 各种业务场景的缓存键 */
    // 生成链接缓存键
    const PRODUCT_DETAIL_GET_LINK_CACHE_KEY = 'product_detail_get_link';
    // 类目列表缓存键
    const PRODUCT_CATEGORY_LIST_CACHE_KEY = 'product_category_list';

    // 防止队列重复消费键
    const CHECK_QUEUE_REPEAT_CONSUMING_KEY = 'check_queue_repeat_consuming';
}

4.创建缓存帮助类

提供了两种方法设置缓存 setCacheData与remember方法 使用前都需先调用setCacheConfig方法

<?php
declare(strict_types=1);

namespace core\Library;

use app\common\enum\CacheEnum;
use think\facade\Cache;

/**
 * 缓存类
 * 注意事项 需先调用setCacheConfig方法
 * Class CacheHelper
 * @package core\Library
 */
class CacheHelper
{
    // 初始版本号
    protected int $version = CacheEnum::DEFAULT_VERSION;

    // 是否自定义缓存键
    protected bool $is_set_version = false;

    // 缓存时间
    protected int|null $ttl = null;

    // 缓存键
    protected string $cache_key = 'default';

    // 未拼接前的缓存键
    protected string $cache_key_ori = 'default';


    // 版本号键
    protected string $version_key = 'default';

    /**
     * 使用闭包缓存
     * @param \Closure $callback
     * @return mixed
     */
    public function remember(\Closure $callback): mixed
    {
        // 获取缓存数据
        $cache_data = $this->getCacheData();
        if ($cache_data !== null) {
            return $cache_data;
        }

        // 缓存不存在,调用闭包生成数据
        $data = $callback();
        // 设置缓存与版本号
        $this->setCacheData($data);

        return $data;
    }


    /**
     * 设置缓存数据
     * @param mixed $data
     * @return bool
     */
    public function setCacheData(mixed $data): bool
    {
        $data_res = Cache::set($this->getCacheKey(), $data, $this->getTtl());
        $version_res = Cache::set($this->getVersionKey(), $this->getVersion());
        if ($data_res && $version_res) {
            return true;
        }
        return false;
    }

    /**
     * 获取缓存数据
     * @return mixed
     */
    public function getCacheData(): mixed
    {
        if (Cache::has($this->getCacheKey())) {
            return Cache::get($this->getCacheKey());
        }
        return null;
    }


    /**
     * 获取当前缓存版本号
     * @return int
     */
    public function getVersion(): int
    {
        if (!$this->is_set_version && Cache::has($this->version_key)) {
            // 未手动设置过缓存 缓存存在,直接返回
            $this->version = intval(Cache::get($this->version_key));
        }
        return $this->version;
    }


    /**
     * 设置缓存配置
     * @param string $cache_key 缓存键名
     * @param int|null $ttl 缓存有效期 null为永久有效
     * @param bool $inc_version 是否递增版本号
     * @param int $version 是否自定义版本号 不建议与递增版本号同时使用 若同时使用 则会在自定义版本号基础上加1
     * @return $this
     */
    public function setCacheConfig(string $cache_key, int|null $ttl = null, bool $inc_version = false, int $version = 0): self
    {
        $this->cache_key_ori = $cache_key;
        $this->setVersionKey();

        // 若指定版本号则设置
        !empty($version) && $this->setVersion($version);

        // 获取当前版本号 +1
        $version = $this->getVersion();
        $inc_version && $this->setVersion($version + 1);

        // 设置缓存时间
        !is_null($ttl) && $this->ttl = $ttl;

        $this->cache_key = $this->generateCacheKey($this->getVersion());
        return $this;
    }

    /**
     * 生成缓存键名
     * @param int $version
     * @return string
     */
    protected function generateCacheKey(int $version): string
    {
        return CacheEnum::CACHE_PREFIX . ':' . $this->getEnv() . ':' . $this->cache_key_ori . ':' . $version;
    }

    public function getEnv(): string
    {
        return app('env')->get('app_env') ?? 'dev';
    }

    /**
     * 获取有效期
     * @return int|null
     */
    public function getTtl(): int|null
    {
        return $this->ttl;
    }

    /**
     * 获取缓存键名
     * @return string
     */
    public function getCacheKey(): string
    {
        return $this->cache_key;
    }

    /**
     * 删除缓存
     * @param array $version_list 版本号列表
     * @return bool
     */
    public function delete(array $version_list): bool
    {
        if (!$version_list) {
            return true;
        }
        foreach ($version_list as $version) {
            $cache_key = $this->generateCacheKey($version);
            Cache::delete($cache_key);
        }
        return true;
    }

    /**
     * 获取历史版本缓存 不包含当前版本
     * @return array
     */
    public function getHistoryVersion(): array
    {
        $version_list = [];
        for ($i = CacheEnum::DEFAULT_VERSION; $i < $this->getVersion(); $i++) {
            $cache_key = $this->generateCacheKey($i);
            if (Cache::has($cache_key)) {
                $version_list[] = $i;
            }
        }
        return $version_list;
    }

    /**
     * 手动设置缓存版本号
     * @param int $version
     * @return $this
     */
    protected function setVersion(int $version): self
    {
        $this->version = $version;
        $this->is_set_version = true;
        return $this;
    }


    /**
     * 获取版本号键名
     * @return string
     */
    protected function getVersionKey(): string
    {
        return $this->version_key;
    }


    /**
     * 设置缓存版本键名
     * @return $this
     */
    protected function setVersionKey(): self
    {
        $this->version_key = CacheEnum::CACHE_VERSION_PREFIX . ':' . $this->getEnv() . ':' . $this->cache_key_ori;
        return $this;
    }
}

5. 使用方法

首先注入帮助类

#[Inject]
protected CacheHelper $cacheHelper;
  1. 使用闭包方式设置缓存 若缓存不存在执行闭包返回结果(适合返回结果处理比较简单的情况 这样简洁一些)
$level = 1;
$cache_key = CacheEnum::PRODUCT_CATEGORY_LIST_CACHE_KEY . "_{$level}";
return $this->cacheHelper->setCacheConfig($cache_key, 3600 * 24 * 4)->remember(function () use ($params) {
    return $this->getListByLevel($params);
});
  1. 手动判断缓存 是否为空 处理业务(适合逻辑比较复杂的情况)
$cache_key = CacheEnum::PRODUCT_DETAIL_GET_LINK_CACHE_KEY . "_{$type}";
$cache = $this->cacheHelper->setCacheConfig($cache_key, 3600 * 24);

if (!empty($cache_data = $cache->getCacheData())) {
    return $cache_data;
}

// todo 处理业务 获取结果
$return_data = ['aaa'];

// 设置缓存
!empty($return_data) && $cache->setCacheData($return_data);

// 返回结果
return $return_data;

6. 扩展用法

自增缓存版本号

$cache = $this->cacheHelper->setCacheConfig($cache_key, 3600 * 24, true);

指定版本号缓存(如果指定版本号缓存 第三个参数传false,如果传true 以下示例的版本号会变成1010)

$cache = $this->cacheHelper->setCacheConfig($cache_key, 3600 * 24, false, 1009);

获取当前版本之前的历史版本号 (初始版本号为1001 以下示例为获取 1001~1008版本的缓存)

$cache = $this->cacheHelper->setCacheConfig($cache_key, 3600 * 24, false, 1009);
$history_version_list = $cache->getHistoryVersion();

删除指定版本号列表的缓存

$this->cacheHelper->setCacheConfig($cache_key)->delete([1001,1002]);
0

评论区