|
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\Memcache; |
|
18
|
|
|
|
|
19
|
|
|
use DateTime; |
|
20
|
|
|
use Exception; |
|
21
|
|
|
use Memcache as MemcacheSoftware; |
|
22
|
|
|
use Phpfastcache\Cluster\AggregatablePoolInterface; |
|
23
|
|
|
use Phpfastcache\Config\ConfigurationOption; |
|
24
|
|
|
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface; |
|
25
|
|
|
use Phpfastcache\Core\Pool\TaggableCacheItemPoolTrait; |
|
26
|
|
|
use Phpfastcache\Core\Item\ExtendedCacheItemInterface; |
|
27
|
|
|
use Phpfastcache\Entities\DriverStatistic; |
|
28
|
|
|
use Phpfastcache\Event\EventManagerInterface; |
|
29
|
|
|
use Phpfastcache\Exceptions\PhpfastcacheCoreException; |
|
30
|
|
|
use Phpfastcache\Exceptions\PhpfastcacheDriverCheckException; |
|
31
|
|
|
use Phpfastcache\Exceptions\PhpfastcacheDriverConnectException; |
|
32
|
|
|
use Phpfastcache\Exceptions\PhpfastcacheDriverException; |
|
33
|
|
|
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException; |
|
34
|
|
|
use Phpfastcache\Exceptions\PhpfastcacheIOException; |
|
35
|
|
|
use Phpfastcache\Exceptions\PhpfastcacheLogicException; |
|
36
|
|
|
use Phpfastcache\Util\MemcacheDriverCollisionDetectorTrait; |
|
37
|
|
|
|
|
38
|
|
|
/** |
|
39
|
|
|
* @property MemcacheSoftware $instance |
|
40
|
|
|
* @method Config getConfig() |
|
41
|
|
|
*/ |
|
42
|
|
|
class Driver implements AggregatablePoolInterface |
|
43
|
|
|
{ |
|
44
|
|
|
use TaggableCacheItemPoolTrait { |
|
45
|
|
|
__construct as protected __parentConstruct; |
|
46
|
|
|
} |
|
47
|
|
|
use MemcacheDriverCollisionDetectorTrait; |
|
48
|
|
|
|
|
49
|
|
|
protected int $memcacheFlags = 0; |
|
50
|
|
|
|
|
51
|
|
|
/** |
|
52
|
|
|
* Driver constructor. |
|
53
|
|
|
* @param ConfigurationOption $config |
|
54
|
|
|
* @param string $instanceId |
|
55
|
|
|
* @param EventManagerInterface $em |
|
56
|
|
|
* @throws PhpfastcacheDriverConnectException |
|
57
|
|
|
* @throws PhpfastcacheInvalidArgumentException |
|
58
|
|
|
* @throws PhpfastcacheCoreException |
|
59
|
|
|
* @throws PhpfastcacheDriverCheckException |
|
60
|
|
|
* @throws PhpfastcacheIOException |
|
61
|
|
|
*/ |
|
62
|
|
|
public function __construct(ConfigurationOption $config, string $instanceId, EventManagerInterface $em) |
|
63
|
|
|
{ |
|
64
|
|
|
self::checkCollision('Memcache'); |
|
65
|
|
|
$this->__parentConstruct($config, $instanceId, $em); |
|
66
|
|
|
} |
|
67
|
|
|
|
|
68
|
|
|
/** |
|
69
|
|
|
* @return bool |
|
70
|
|
|
*/ |
|
71
|
|
|
public function driverCheck(): bool |
|
72
|
|
|
{ |
|
73
|
|
|
return class_exists('Memcache'); |
|
74
|
|
|
} |
|
75
|
|
|
|
|
76
|
|
|
/** |
|
77
|
|
|
* @return DriverStatistic |
|
78
|
|
|
*/ |
|
79
|
|
|
public function getStats(): DriverStatistic |
|
80
|
|
|
{ |
|
81
|
|
|
$stats = (array)$this->instance->getstats(); |
|
82
|
|
|
$stats['uptime'] = (isset($stats['uptime']) ? $stats['uptime'] : 0); |
|
83
|
|
|
$stats['version'] = (isset($stats['version']) ? $stats['version'] : 'UnknownVersion'); |
|
84
|
|
|
$stats['bytes'] = (isset($stats['bytes']) ? $stats['version'] : 0); |
|
85
|
|
|
|
|
86
|
|
|
$date = (new DateTime())->setTimestamp(time() - $stats['uptime']); |
|
87
|
|
|
|
|
88
|
|
|
return (new DriverStatistic()) |
|
|
|
|
|
|
89
|
|
|
->setData(implode(', ', array_keys($this->itemInstances))) |
|
90
|
|
|
->setInfo(sprintf("The memcache daemon v%s is up since %s.\n For more information see RawData.", $stats['version'], $date->format(DATE_RFC2822))) |
|
91
|
|
|
->setRawData($stats) |
|
92
|
|
|
->setSize((int)$stats['bytes']); |
|
93
|
|
|
} |
|
94
|
|
|
|
|
95
|
|
|
/** |
|
96
|
|
|
* @return bool |
|
97
|
|
|
* @throws PhpfastcacheDriverException |
|
98
|
|
|
*/ |
|
99
|
|
|
protected function driverConnect(): bool |
|
100
|
|
|
{ |
|
101
|
|
|
$this->instance = new MemcacheSoftware(); |
|
102
|
|
|
|
|
103
|
|
|
foreach ($this->getConfig()->getServers() as $server) { |
|
104
|
|
|
try { |
|
105
|
|
|
/** |
|
106
|
|
|
* If path is provided we consider it as a UNIX Socket |
|
107
|
|
|
*/ |
|
108
|
|
|
if (!empty($server['path'])) { |
|
109
|
|
|
$this->instance->addServer($server['path'], 0); |
|
110
|
|
|
} elseif (!empty($server['host'])) { |
|
111
|
|
|
$this->instance->addServer($server['host'], $server['port']); |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
if (!empty($server['saslUser']) && !empty($server['saslPassword'])) { |
|
115
|
|
|
throw new PhpfastcacheDriverException('Unlike Memcached, Memcache does not support SASL authentication'); |
|
116
|
|
|
} |
|
117
|
|
|
} catch (Exception $e) { |
|
118
|
|
|
throw new PhpfastcacheDriverConnectException( |
|
119
|
|
|
sprintf( |
|
120
|
|
|
'Failed to connect to memcache host/path "%s" with the following error: %s', |
|
121
|
|
|
$server['host'] ?: $server['path'], |
|
122
|
|
|
$e->getMessage() |
|
123
|
|
|
) |
|
124
|
|
|
); |
|
125
|
|
|
} |
|
126
|
|
|
|
|
127
|
|
|
/** |
|
128
|
|
|
* Since Memcached does not throw |
|
129
|
|
|
* any error if not connected ... |
|
130
|
|
|
*/ |
|
131
|
|
|
if ( |
|
132
|
|
|
!$this->instance->getServerStatus( |
|
133
|
|
|
!empty($server['path']) ? $server['path'] : $server['host'], |
|
134
|
|
|
!empty($server['port']) ? $server['port'] : 0 |
|
135
|
|
|
) |
|
136
|
|
|
) { |
|
137
|
|
|
throw new PhpfastcacheDriverException('Memcache seems to not be connected'); |
|
138
|
|
|
} |
|
139
|
|
|
} |
|
140
|
|
|
|
|
141
|
|
|
return true; |
|
142
|
|
|
} |
|
143
|
|
|
|
|
144
|
|
|
/** |
|
145
|
|
|
* @param ExtendedCacheItemInterface $item |
|
146
|
|
|
* @return ?array<string, mixed> |
|
147
|
|
|
*/ |
|
148
|
|
|
protected function driverRead(ExtendedCacheItemInterface $item): ?array |
|
149
|
|
|
{ |
|
150
|
|
|
$val = $this->instance->get($item->getKey()); |
|
151
|
|
|
|
|
152
|
|
|
if (empty($val) || !\is_array($val)) { |
|
153
|
|
|
return null; |
|
154
|
|
|
} |
|
155
|
|
|
|
|
156
|
|
|
return $val; |
|
157
|
|
|
} |
|
158
|
|
|
|
|
159
|
|
|
/** |
|
160
|
|
|
* @param ExtendedCacheItemInterface $item |
|
161
|
|
|
* @return mixed |
|
162
|
|
|
* @throws PhpfastcacheInvalidArgumentException |
|
163
|
|
|
* @throws PhpfastcacheLogicException |
|
164
|
|
|
*/ |
|
165
|
|
|
protected function driverWrite(ExtendedCacheItemInterface $item): bool |
|
166
|
|
|
{ |
|
167
|
|
|
|
|
168
|
|
|
$ttl = $item->getExpirationDate()->getTimestamp() - time(); |
|
169
|
|
|
|
|
170
|
|
|
// Memcache will only allow an expiration timer less than 2592000 seconds, |
|
171
|
|
|
// otherwise, it will assume you're giving it a UNIX timestamp. |
|
172
|
|
|
if ($ttl > 2592000) { |
|
173
|
|
|
$ttl = time() + $ttl; |
|
174
|
|
|
} |
|
175
|
|
|
return $this->instance->set($item->getKey(), $this->driverPreWrap($item), $this->memcacheFlags, $ttl); |
|
176
|
|
|
} |
|
177
|
|
|
|
|
178
|
|
|
/** |
|
179
|
|
|
* @param string $key |
|
180
|
|
|
* @param string $encodedKey |
|
181
|
|
|
* @return bool |
|
182
|
|
|
*/ |
|
183
|
|
|
protected function driverDelete(string $key, string $encodedKey): bool |
|
184
|
|
|
{ |
|
185
|
|
|
return $this->instance->delete($key); |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
/** |
|
189
|
|
|
* @return bool |
|
190
|
|
|
*/ |
|
191
|
|
|
protected function driverClear(): bool |
|
192
|
|
|
{ |
|
193
|
|
|
return $this->instance->flush(); |
|
194
|
|
|
} |
|
195
|
|
|
} |
|
196
|
|
|
|
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.