Skip to content

Commit 40eddad

Browse files
committed
Add full phpredis support to the cache component
- Improved the RedisStore to support phpredis serialization and compression settings. - Improve test suite related to phpredis.
1 parent 60d60b0 commit 40eddad

19 files changed

+1492
-1345
lines changed

src/Illuminate/Cache/LuaScripts.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,22 @@ public static function releaseLock()
2020
else
2121
return 0
2222
end
23+
LUA;
24+
}
25+
26+
/**
27+
* Get the Lua script that sets a key only when it does not yet exist.
28+
*
29+
* KEYS[1] - The name of the key
30+
* ARGV[1] - Value of the key
31+
* ARGV[2] - Time in seconds how long to keep the key
32+
*
33+
* @return string
34+
*/
35+
public static function add()
36+
{
37+
return <<<'LUA'
38+
return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])
2339
LUA;
2440
}
2541
}

src/Illuminate/Cache/RedisStore.php

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,11 @@ public function __construct(Redis $redis, $prefix = '', $connection = 'default')
5959
*/
6060
public function get($key)
6161
{
62-
$value = $this->connection()->get($this->prefix.$key);
62+
$connection = $this->connection();
6363

64-
return ! is_null($value) ? $this->unserialize($value) : null;
64+
$value = $connection->get($this->prefix.$key);
65+
66+
return $value === null ? null : $this->connectionAwareUnserialize($value, $connection);
6567
}
6668

6769
/**
@@ -76,12 +78,14 @@ public function many(array $keys)
7678
{
7779
$results = [];
7880

79-
$values = $this->connection()->mget(array_map(function ($key) {
81+
$connection = $this->connection();
82+
83+
$values = $connection->mget(array_map(function ($key) {
8084
return $this->prefix.$key;
8185
}, $keys));
8286

8387
foreach ($values as $index => $value) {
84-
$results[$keys[$index]] = ! is_null($value) ? $this->unserialize($value) : null;
88+
$results[$keys[$index]] = $value === null ? null : $this->connectionAwareUnserialize($value, $connection);
8589
}
8690

8791
return $results;
@@ -97,8 +101,10 @@ public function many(array $keys)
97101
*/
98102
public function put($key, $value, $seconds)
99103
{
100-
return (bool) $this->connection()->setex(
101-
$this->prefix.$key, (int) max(1, $seconds), $this->serialize($value)
104+
$connection = $this->connection();
105+
106+
return (bool) $connection->setex(
107+
$this->prefix.$key, (int) max(1, $seconds), $this->connectionAwareSerialize($value, $connection)
102108
);
103109
}
104110

@@ -136,10 +142,10 @@ public function putMany(array $values, $seconds)
136142
*/
137143
public function add($key, $value, $seconds)
138144
{
139-
$lua = "return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])";
145+
$connection = $this->connection();
140146

141-
return (bool) $this->connection()->eval(
142-
$lua, 1, $this->prefix.$key, $this->serialize($value), (int) max(1, $seconds)
147+
return (bool) $connection->eval(
148+
LuaScripts::add(), 1, $this->prefix.$key, $this->pack($value, $connection), (int) max(1, $seconds)
143149
);
144150
}
145151

@@ -176,7 +182,9 @@ public function decrement($key, $value = 1)
176182
*/
177183
public function forever($key, $value)
178184
{
179-
return (bool) $this->connection()->set($this->prefix.$key, $this->serialize($value));
185+
$connection = $this->connection();
186+
187+
return (bool) $connection->set($this->prefix.$key, $this->connectionAwareSerialize($value, $connection));
180188
}
181189

182190
/**
@@ -344,4 +352,58 @@ protected function unserialize($value)
344352
{
345353
return is_numeric($value) ? $value : unserialize($value);
346354
}
355+
356+
/**
357+
* Prepares a value to be used with the redis cache store when used with eval scripts.
358+
*
359+
* @param mixed $value
360+
* @param \Illuminate\Redis\Connections\Connection $connection
361+
* @return mixed
362+
*/
363+
protected function pack($value, $connection)
364+
{
365+
if ($connection instanceof PhpRedisConnection) {
366+
if ($connection->serialized()) {
367+
return $connection->pack([$value])[0];
368+
}
369+
370+
if ($connection->compressed()) {
371+
return $connection->pack([$this->serialize($value)])[0];
372+
}
373+
}
374+
375+
return $this->serialize($value);
376+
}
377+
378+
/**
379+
* Does connection specific considerations when a value needs to be serialized.
380+
*
381+
* @param mixed $value
382+
* @param \Illuminate\Redis\Connections\Connection $connection
383+
* @return mixed
384+
*/
385+
protected function connectionAwareSerialize($value, $connection)
386+
{
387+
if ($connection instanceof PhpRedisConnection && $connection->serialized()) {
388+
return $value;
389+
}
390+
391+
return $this->serialize($value);
392+
}
393+
394+
/**
395+
* Does connection specific considerations when a value needs to be unserialized.
396+
*
397+
* @param mixed $value
398+
* @param \Illuminate\Redis\Connections\Connection $connection
399+
* @return mixed
400+
*/
401+
protected function connectionAwareUnserialize($value, $connection)
402+
{
403+
if ($connection instanceof PhpRedisConnection && $connection->serialized()) {
404+
return $value;
405+
}
406+
407+
return $this->unserialize($value);
408+
}
347409
}

0 commit comments

Comments
 (0)