分类
碎碎念

【PHP】分享一个基于 Redis 简单封装的缓存类

带有自动链接、数组存取、序列化存取、锁等等

<?php

class Cache
{
    /**
     * @var bool
     */
    static protected $_persistent = true;

    /**
     * @var \Redis
     */
    static protected $_redis;

    /**
     * @var string
     */
    static protected $_prefix;

    /**
     * connect 初始化链接
     *
     * @param string $host
     * @param int $port
     * @param int $db
     */
    static public function connect($host = '127.0.0.1', $port = 6379, $db = null)
    {
        if (class_exists('\\Redis')) {
            try {
                self::$_redis = new \Redis();
                if (self::$_persistent) {
                    self::$_redis->pconnect($host, $port);
                } else {
                    self::$_redis->connect($host, $port);
                }
                if ($db !== null) {
                    self::$_redis->select($db);
                }
            } catch (Exception $e) {
                self::$_redis = false;
            }
        } else {
            self::$_redis = false;
        }
    }

    /**
     * redis 获取 Redis 对象
     *
     * @return bool|\Redis
     */
    static public function redis()
    {
        if (self::_check()) {
            return self::$_redis;
        }
        return false;
    }

    /**
     * string 获取或保存字符串
     *
     * @param string $key
     * @param string $value
     * @param int $ttl
     * @return bool|string
     */
    static public function string($key, $value = null, $ttl = 0)
    {
        if (self::_check()) {
            $key = self::key($key);
            if ($value === null) {
                return self::$_redis->get($key);
            } else {
                if ($ttl > 0) {
                    return self::$_redis->setex($key, $ttl, $value);
                } else {
                    return self::$_redis->set($key, $value);
                }
            }
        }
        return false;
    }

    /**
     * json 获取或保存数组
     *
     * @param string $key
     * @param array $value
     * @param int $ttl
     * @return bool|array
     */
    static public function json($key, $value = null, $ttl = 0)
    {
        if (self::_check()) {
            if ($value === null) {
                $value = json_decode(self::string($key), true);
                if (json_last_error() === JSON_ERROR_NONE) {
                    return $value;
                } else {
                    return false;
                }
            } else {
                return self::string($key, json_encode($value), $ttl);
            }
        }
        return false;
    }

    /**
     * serialize 获取或保存序列化
     *
     * @param string $key
     * @param mixed $value
     * @param int $ttl
     * @return bool|mixed
     */
    static public function serialize($key, $value = null, $ttl = 0)
    {
        if (self::_check()) {
            if ($value === null) {
                return unserialize(self::string($key));
            } else {
                return self::string($key, serialize($value), $ttl);
            }
        }
        return false;
    }

    /**
     * ttl 获取或设置过期时间
     *
     * @param string $key
     * @param int $ttl
     * @return bool|int
     */
    static public function ttl($key, $ttl = null)
    {
        if (self::_check()) {
            $key = self::key($key);
            if ($ttl === null) {
                return self::$_redis->ttl($key);
            } else {
                return self::$_redis->expire($key, $ttl);
            }
        }
        return false;
    }

    /**
     * delete 删除缓存
     *
     * @param string $key
     * @return bool
     */
    static public function delete($key)
    {
        if (self::_check()) {
            return self::$_redis->del(self::key($key));
        }
        return false;
    }

    /**
     * exists 检查缓存是否存在
     *
     * @param string $key
     * @return bool
     */
    static public function exists($key)
    {
        if (self::_check()) {
            return self::$_redis->exists(self::key($key));
        }
        return false;
    }

    /**
     * prefix 获取或设置键名前缀
     *
     * @param string $prefix
     * @return string
     */
    static public function prefix($prefix = null)
    {
        if ($prefix !== null && self::$_prefix !== $prefix) {
            self::$_prefix = $prefix;
        }
        return self::$_prefix;
    }

    /**
     * lock 设置锁
     *
     * @param string $key
     * @param string $token
     * @param int $ttl
     * @return bool
     */
    static public function lock($key, $token = null, $ttl = null)
    {
        if (self::_check()) {
            $key = self::key($key);
            $token = 'LOCK:' . ($token === null ? $key : $token);
            if (self::$_redis->setnx($key, $token)) {
                if ($ttl !== null) {
                    self::$_redis->expire($key, $ttl);
                }
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    /**
     * unlock 解除锁
     *
     * @param string $key
     * @param string $token
     * @param int $delay
     * @return bool
     */
    static public function unlock($key, $token = null, $delay = 0)
    {
        if (self::_check()) {
            $key = self::key($key);
            $token = 'LOCK:' . ($token === null ? $key : $token);
            $script = <<<EOL
if redis.call("get", KEYS[1]) == ARGV[1] then
    if tonumber(ARGV[2]) > 0 then
        -- 延迟删除
        redis.call("set", KEYS[1], "Waiting for automatic unlocking")
        return redis.call("expire", KEYS[1], ARGV[2])
    else
        -- 立即删除
        return redis.call("del", KEYS[1])
    end
else
    return 0
end
EOL;
            return self::$_redis->eval($script, [$key, $token, $delay], 1);
        }
        return false;
    }

    /**
     * key 获取键名
     *
     * @param string $key
     * @return string
     */
    static public function key($key)
    {
        if (empty(self::$_prefix)) {
            return $key;
        } else {
            return self::$_prefix . ':' . $key;
        }
    }

    /**
     * _check 检查或链接 Redis
     *
     * @return bool
     */
    static private function _check()
    {
        if (self::$_redis === null) {
            self::connect();
        }
        return self::$_redis !== false;
    }

    /**
     * __callStatic 静态魔术方法(原生 \Redis 方法)
     *
     * @param string $name
     * @param array $arguments
     * @return mixed
     */
    static public function __callStatic($name, $arguments)
    {
        if (self::_check()) {
            return call_user_func_array([self::$_redis, $name], $arguments);
        }
        return false;
    }
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据