|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* |
|
5
|
|
|
* This file is part of Phpfastcache. |
|
6
|
|
|
* |
|
7
|
|
|
* @license MIT License (MIT) |
|
8
|
|
|
* |
|
9
|
|
|
* For full copyright and license information, please see the docs/CREDITS.txt and LICENCE files. |
|
10
|
|
|
* |
|
11
|
|
|
* @author Georges.L (Geolim4) <[email protected]> |
|
12
|
|
|
* @author Contributors https://github.com/PHPSocialNetwork/phpfastcache/graphs/contributors |
|
13
|
|
|
*/ |
|
14
|
|
|
|
|
15
|
|
|
declare(strict_types=1); |
|
16
|
|
|
|
|
17
|
|
|
namespace Phpfastcache\Drivers\Redis; |
|
18
|
|
|
|
|
19
|
|
|
use DateTime; |
|
20
|
|
|
use Phpfastcache\Cluster\AggregatablePoolInterface; |
|
21
|
|
|
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface; |
|
22
|
|
|
use Phpfastcache\Core\Pool\TaggableCacheItemPoolTrait; |
|
23
|
|
|
use Phpfastcache\Entities\DriverStatistic; |
|
24
|
|
|
use Phpfastcache\Exceptions\PhpfastcacheLogicException; |
|
25
|
|
|
use Redis as RedisClient; |
|
26
|
|
|
|
|
27
|
|
|
/** |
|
28
|
|
|
* @property RedisClient $instance |
|
29
|
|
|
* @method Config getConfig() |
|
30
|
|
|
*/ |
|
31
|
|
|
class Driver implements AggregatablePoolInterface |
|
32
|
|
|
{ |
|
33
|
|
|
use RedisDriverTrait, TaggableCacheItemPoolTrait { |
|
34
|
|
|
RedisDriverTrait::driverReadMultiple insteadof TaggableCacheItemPoolTrait; |
|
35
|
|
|
RedisDriverTrait::driverDeleteMultiple insteadof TaggableCacheItemPoolTrait; |
|
36
|
|
|
} |
|
37
|
|
|
|
|
38
|
|
|
|
|
39
|
|
|
/** |
|
40
|
|
|
* @return bool |
|
41
|
|
|
*/ |
|
42
|
|
|
public function driverCheck(): bool |
|
43
|
|
|
{ |
|
44
|
|
|
return extension_loaded('Redis') && class_exists(RedisClient::class); |
|
45
|
|
|
} |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* @return DriverStatistic |
|
49
|
|
|
*/ |
|
50
|
|
|
public function getStats(): DriverStatistic |
|
51
|
|
|
{ |
|
52
|
|
|
// used_memory |
|
53
|
|
|
$info = $this->instance->info(); |
|
54
|
|
|
$date = (new DateTime())->setTimestamp(time() - $info['uptime_in_seconds']); |
|
55
|
|
|
|
|
56
|
|
|
return (new DriverStatistic()) |
|
|
|
|
|
|
57
|
|
|
->setData(implode(', ', array_keys($this->itemInstances))) |
|
58
|
|
|
->setRawData($info) |
|
59
|
|
|
->setSize((int)$info['used_memory_dataset']) |
|
60
|
|
|
->setInfo( |
|
61
|
|
|
sprintf( |
|
62
|
|
|
"The Redis daemon v%s, php-ext v%s, is up since %s.\n For more information see RawData.", |
|
63
|
|
|
$info['redis_version'], |
|
64
|
|
|
\phpversion("redis"), |
|
65
|
|
|
$date->format(DATE_RFC2822) |
|
66
|
|
|
) |
|
67
|
|
|
); |
|
68
|
|
|
} |
|
69
|
|
|
|
|
70
|
|
|
/** |
|
71
|
|
|
* @return bool |
|
72
|
|
|
* @throws PhpfastcacheLogicException |
|
73
|
|
|
*/ |
|
74
|
|
|
protected function driverConnect(): bool |
|
75
|
|
|
{ |
|
76
|
|
|
if (isset($this->instance) && $this->instance instanceof RedisClient) { |
|
77
|
|
|
throw new PhpfastcacheLogicException('Already connected to Redis server'); |
|
78
|
|
|
} |
|
79
|
|
|
|
|
80
|
|
|
/** |
|
81
|
|
|
* In case of an user-provided |
|
82
|
|
|
* Redis client just return here |
|
83
|
|
|
*/ |
|
84
|
|
|
if ($this->getConfig()->getRedisClient() instanceof RedisClient) { |
|
85
|
|
|
/** |
|
86
|
|
|
* Unlike Predis, we can't test if we're connected |
|
87
|
|
|
* or not, so let's just assume that we are |
|
88
|
|
|
*/ |
|
89
|
|
|
$this->instance = $this->getConfig()->getRedisClient(); |
|
90
|
|
|
return true; |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
|
$this->instance = $this->instance ?? new RedisClient(); |
|
94
|
|
|
|
|
95
|
|
|
/** |
|
96
|
|
|
* If path is provided we consider it as a UNIX Socket |
|
97
|
|
|
*/ |
|
98
|
|
|
if ($this->getConfig()->getPath()) { |
|
99
|
|
|
$isConnected = $this->instance->connect($this->getConfig()->getPath()); |
|
100
|
|
|
} else { |
|
101
|
|
|
$isConnected = $this->instance->connect($this->getConfig()->getHost(), $this->getConfig()->getPort(), $this->getConfig()->getTimeout()); |
|
102
|
|
|
} |
|
103
|
|
|
|
|
104
|
|
|
if (!$isConnected && $this->getConfig()->getPath()) { |
|
105
|
|
|
return false; |
|
106
|
|
|
} |
|
107
|
|
|
|
|
108
|
|
|
if ($this->getConfig()->getOptPrefix()) { |
|
109
|
|
|
$this->instance->setOption(RedisClient::OPT_PREFIX, $this->getConfig()->getOptPrefix()); |
|
110
|
|
|
} |
|
111
|
|
|
|
|
112
|
|
|
if ($this->getConfig()->getPassword() && !$this->instance->auth($this->getConfig()->getPassword())) { |
|
113
|
|
|
return false; |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
if ($this->getConfig()->getDatabase() !== null) { |
|
|
|
|
|
|
117
|
|
|
$this->instance->select($this->getConfig()->getDatabase()); |
|
118
|
|
|
} |
|
119
|
|
|
return true; |
|
120
|
|
|
} |
|
121
|
|
|
|
|
122
|
|
|
/** |
|
123
|
|
|
* @return array<int, string> |
|
124
|
|
|
* @throws \RedisException |
|
125
|
|
|
*/ |
|
126
|
|
|
protected function driverReadAllKeys(string $pattern = '*'): iterable |
|
127
|
|
|
{ |
|
128
|
|
|
$i = -1; |
|
129
|
|
|
$keys = $this->instance->scan($i, $pattern === '' ? '*' : $pattern, ExtendedCacheItemPoolInterface::MAX_ALL_KEYS_COUNT); |
|
130
|
|
|
if (is_iterable($keys)) { |
|
131
|
|
|
return $keys; |
|
132
|
|
|
} else { |
|
133
|
|
|
return []; |
|
134
|
|
|
} |
|
135
|
|
|
} |
|
136
|
|
|
|
|
137
|
|
|
/** |
|
138
|
|
|
* @return bool |
|
139
|
|
|
*/ |
|
140
|
|
|
protected function driverClear(): bool |
|
141
|
|
|
{ |
|
142
|
|
|
return $this->instance->flushDB(); |
|
143
|
|
|
} |
|
144
|
|
|
} |
|
145
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.