290 lines
6.4 KiB
PHP
290 lines
6.4 KiB
PHP
<?php
|
|
|
|
namespace Illuminate\Cache;
|
|
|
|
use Illuminate\Contracts\Cache\Store;
|
|
use Illuminate\Contracts\Redis\Factory as Redis;
|
|
|
|
class RedisStore extends TaggableStore implements Store
|
|
{
|
|
/**
|
|
* The Redis factory implementation.
|
|
*
|
|
* @var \Illuminate\Contracts\Redis\Factory
|
|
*/
|
|
protected $redis;
|
|
|
|
/**
|
|
* A string that should be prepended to keys.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $prefix;
|
|
|
|
/**
|
|
* The Redis connection that should be used.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $connection;
|
|
|
|
/**
|
|
* Create a new Redis store.
|
|
*
|
|
* @param \Illuminate\Contracts\Redis\Factory $redis
|
|
* @param string $prefix
|
|
* @param string $connection
|
|
* @return void
|
|
*/
|
|
public function __construct(Redis $redis, $prefix = '', $connection = 'default')
|
|
{
|
|
$this->redis = $redis;
|
|
$this->setPrefix($prefix);
|
|
$this->setConnection($connection);
|
|
}
|
|
|
|
/**
|
|
* Retrieve an item from the cache by key.
|
|
*
|
|
* @param string|array $key
|
|
* @return mixed
|
|
*/
|
|
public function get($key)
|
|
{
|
|
$value = $this->connection()->get($this->prefix.$key);
|
|
|
|
return ! is_null($value) ? $this->unserialize($value) : null;
|
|
}
|
|
|
|
/**
|
|
* Retrieve multiple items from the cache by key.
|
|
*
|
|
* Items not found in the cache will have a null value.
|
|
*
|
|
* @param array $keys
|
|
* @return array
|
|
*/
|
|
public function many(array $keys)
|
|
{
|
|
$results = [];
|
|
|
|
$values = $this->connection()->mget(array_map(function ($key) {
|
|
return $this->prefix.$key;
|
|
}, $keys));
|
|
|
|
foreach ($values as $index => $value) {
|
|
$results[$keys[$index]] = ! is_null($value) ? $this->unserialize($value) : null;
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
/**
|
|
* Store an item in the cache for a given number of minutes.
|
|
*
|
|
* @param string $key
|
|
* @param mixed $value
|
|
* @param float|int $minutes
|
|
* @return void
|
|
*/
|
|
public function put($key, $value, $minutes)
|
|
{
|
|
$this->connection()->setex(
|
|
$this->prefix.$key, (int) max(1, $minutes * 60), $this->serialize($value)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Store multiple items in the cache for a given number of minutes.
|
|
*
|
|
* @param array $values
|
|
* @param float|int $minutes
|
|
* @return void
|
|
*/
|
|
public function putMany(array $values, $minutes)
|
|
{
|
|
$this->connection()->multi();
|
|
|
|
foreach ($values as $key => $value) {
|
|
$this->put($key, $value, $minutes);
|
|
}
|
|
|
|
$this->connection()->exec();
|
|
}
|
|
|
|
/**
|
|
* Store an item in the cache if the key doesn't exist.
|
|
*
|
|
* @param string $key
|
|
* @param mixed $value
|
|
* @param float|int $minutes
|
|
* @return bool
|
|
*/
|
|
public function add($key, $value, $minutes)
|
|
{
|
|
$lua = "return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])";
|
|
|
|
return (bool) $this->connection()->eval(
|
|
$lua, 1, $this->prefix.$key, $this->serialize($value), (int) max(1, $minutes * 60)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Increment the value of an item in the cache.
|
|
*
|
|
* @param string $key
|
|
* @param mixed $value
|
|
* @return int
|
|
*/
|
|
public function increment($key, $value = 1)
|
|
{
|
|
return $this->connection()->incrby($this->prefix.$key, $value);
|
|
}
|
|
|
|
/**
|
|
* Decrement the value of an item in the cache.
|
|
*
|
|
* @param string $key
|
|
* @param mixed $value
|
|
* @return int
|
|
*/
|
|
public function decrement($key, $value = 1)
|
|
{
|
|
return $this->connection()->decrby($this->prefix.$key, $value);
|
|
}
|
|
|
|
/**
|
|
* Store an item in the cache indefinitely.
|
|
*
|
|
* @param string $key
|
|
* @param mixed $value
|
|
* @return void
|
|
*/
|
|
public function forever($key, $value)
|
|
{
|
|
$this->connection()->set($this->prefix.$key, $this->serialize($value));
|
|
}
|
|
|
|
/**
|
|
* Get a lock instance.
|
|
*
|
|
* @param string $name
|
|
* @param int $seconds
|
|
* @return \Illuminate\Contracts\Cache\Lock
|
|
*/
|
|
public function lock($name, $seconds = 0)
|
|
{
|
|
return new RedisLock($this->connection(), $this->prefix.$name, $seconds);
|
|
}
|
|
|
|
/**
|
|
* Remove an item from the cache.
|
|
*
|
|
* @param string $key
|
|
* @return bool
|
|
*/
|
|
public function forget($key)
|
|
{
|
|
return (bool) $this->connection()->del($this->prefix.$key);
|
|
}
|
|
|
|
/**
|
|
* Remove all items from the cache.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function flush()
|
|
{
|
|
$this->connection()->flushdb();
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Begin executing a new tags operation.
|
|
*
|
|
* @param array|mixed $names
|
|
* @return \Illuminate\Cache\RedisTaggedCache
|
|
*/
|
|
public function tags($names)
|
|
{
|
|
return new RedisTaggedCache(
|
|
$this, new TagSet($this, is_array($names) ? $names : func_get_args())
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get the Redis connection instance.
|
|
*
|
|
* @return \Predis\ClientInterface
|
|
*/
|
|
public function connection()
|
|
{
|
|
return $this->redis->connection($this->connection);
|
|
}
|
|
|
|
/**
|
|
* Set the connection name to be used.
|
|
*
|
|
* @param string $connection
|
|
* @return void
|
|
*/
|
|
public function setConnection($connection)
|
|
{
|
|
$this->connection = $connection;
|
|
}
|
|
|
|
/**
|
|
* Get the Redis database instance.
|
|
*
|
|
* @return \Illuminate\Contracts\Redis\Factory
|
|
*/
|
|
public function getRedis()
|
|
{
|
|
return $this->redis;
|
|
}
|
|
|
|
/**
|
|
* Get the cache key prefix.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getPrefix()
|
|
{
|
|
return $this->prefix;
|
|
}
|
|
|
|
/**
|
|
* Set the cache key prefix.
|
|
*
|
|
* @param string $prefix
|
|
* @return void
|
|
*/
|
|
public function setPrefix($prefix)
|
|
{
|
|
$this->prefix = ! empty($prefix) ? $prefix.':' : '';
|
|
}
|
|
|
|
/**
|
|
* Serialize the value.
|
|
*
|
|
* @param mixed $value
|
|
* @return mixed
|
|
*/
|
|
protected function serialize($value)
|
|
{
|
|
return is_numeric($value) ? $value : serialize($value);
|
|
}
|
|
|
|
/**
|
|
* Unserialize the value.
|
|
*
|
|
* @param mixed $value
|
|
* @return mixed
|
|
*/
|
|
protected function unserialize($value)
|
|
{
|
|
return is_numeric($value) ? $value : unserialize($value);
|
|
}
|
|
}
|