带有自动链接、数组存取、序列化存取、锁等等
<?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;
}
}