2 // @generated by docskel.php
5 * Represents a connection to a set of memcached servers.
7 <<__NativeData("MemcachedData")>>
9 // Signifies we have provide a session handler
10 const HAVE_SESSION
= true;
12 * Create a Memcached instance
14 * @param string $persistent_id - By default the Memcached instances are
15 * destroyed at the end of the request. To create an instance that persists
16 * between requests, use persistent_id to specify a unique ID for the
17 * instance. All instances created with the same persistent_id will share the
21 public function __construct(?
string $persistent_id = null): void
;
24 * Add an item under a new key
26 * @param string $key -
27 * @param mixed $value -
28 * @param int $expiration -
30 * @return bool - The Memcached::getResultCode will return
31 * Memcached::RES_NOTSTORED if the key already exists.
33 public function add(mixed $key,
35 int $expiration = 0): bool {
36 return $this->addByKey('', $key, $value, $expiration);
40 * Add an item under a new key on a specific server
42 * @param string $server_key -
43 * @param string $key -
44 * @param mixed $value -
45 * @param int $expiration -
47 * @return bool - The Memcached::getResultCode will return
48 * Memcached::RES_NOTSTORED if the key already exists.
51 public function addByKey(string $server_key,
54 int $expiration = 0): bool;
57 * Add a server to the server pool
59 * @param string $host - The hostname of the memcache server. If the
60 * hostname is invalid, data-related operations will set
61 * Memcached::RES_HOST_LOOKUP_FAILURE result code.
62 * @param int $port - The port on which memcache is running. Usually,
64 * @param int $weight - The weight of the server relative to the total
65 * weight of all the servers in the pool. This controls the probability
66 * of the server being selected for operations. This is used only with
67 * consistent distribution option and usually corresponds to the amount
68 * of memory available to memcache on that server.
73 public function addServer(string $host,
75 int $weight = 0): bool;
78 * Add multiple servers to the server pool
80 * @param array $servers -
84 public function addServers(array<array<mixed>> $servers): bool {
85 $servers_vals = array_values($servers);
86 foreach($servers_vals as $i => $server) {
87 $server = array_values($server);
88 if (!is_array($server)) {
90 sprintf('Server list entry #%d is not an array', $i +
1),
95 if (count($server) < 1) {
97 sprintf('Could not get server host for entry #%d', $i +
1),
102 if (count($server) < 2) {
104 sprintf('Could not get server port for entry #%d', $i +
1),
110 $host = (string)$server[0];
111 $port = (int)$server[1];
112 if (count($server) < 3) {
115 $weight = (int)$server[2];
118 if (!$this->addServer($host, $port, $weight)) {
120 sprintf('Could not add entry #%d to the server list', $i +
1),
129 * Append data to an existing item
131 * @param string $key -
132 * @param string $value - The string to append.
134 * @return bool - The Memcached::getResultCode will return
135 * Memcached::RES_NOTSTORED if the key does not exist.
137 public function append(mixed $key,
138 mixed $value): bool {
139 return $this->appendByKey('', $key, $value);
143 * Append data to an existing item on a specific server
145 * @param string $server_key -
146 * @param string $key -
147 * @param string $value - The string to append.
149 * @return bool - The Memcached::getResultCode will return
150 * Memcached::RES_NOTSTORED if the key does not exist.
153 public function appendByKey(string $server_key,
155 string $value): bool;
158 * Compare and swap an item
160 * @param float $cas_token - Unique value associated with the existing
161 * item. Generated by memcache.
162 * @param string $key -
163 * @param mixed $value -
164 * @param int $expiration -
166 * @return bool - The Memcached::getResultCode will return
167 * Memcached::RES_DATA_EXISTS if the item you are trying to store has
168 * been modified since you last fetched it.
170 public function cas(float $cas_token,
173 int $expiration = 0): bool {
174 return $this->casByKey($cas_token, '', $key, $value, $expiration);
178 * Compare and swap an item on a specific server
180 * @param float $cas_token - Unique value associated with the existing
181 * item. Generated by memcache.
182 * @param string $server_key -
183 * @param string $key -
184 * @param mixed $value -
185 * @param int $expiration -
187 * @return bool - The Memcached::getResultCode will return
188 * Memcached::RES_DATA_EXISTS if the item you are trying to store has
189 * been modified since you last fetched it.
192 public function casByKey(float $cas_token,
196 int $expiration = 0): bool;
199 * Decrement numeric item's value
201 * @param string $key - The key of the item to decrement.
202 * @param int $offset - The amount by which to decrement the item's
204 * @param mixed $initial_value - The value to set the item to if it
205 * doesn't currently exist. False to fail if the key does not exist
206 * @param int $expiry - The expiry time to set on the item.
208 * @return mixed - Returns item's new value on success. False if the key
209 * doesn't exist and no initial_value was provided.
212 public function decrement(string $key,
214 mixed $initial_value = false,
215 int $expiry = 0): mixed;
218 * Decrement numeric item's value, stored on a specific server
220 * @param string $server_key -
221 * @param string $key - The key of the item to decrement.
222 * @param int $offset - The amount by which to decrement the item's
224 * @param int $initial_value - The value to set the item to if it
225 * doesn't currently exist. False to fail if the key does not exist.
226 * @param int $expiry - The expiry time to set on the item.
228 * @return int - Returns item's new value on success. False if the key
229 * doesn't exist and no initial_value was provided.
232 public function decrementByKey(string $server_key,
235 mixed $initial_value = false,
236 int $expiry = 0): mixed;
241 * @param string $key - The key to be deleted.
242 * @param int $time - The amount of time the server will wait to delete
245 * @return bool - The Memcached::getResultCode will return
246 * Memcached::RES_NOTFOUND if the key does not exist.
248 public function delete(mixed $key,
249 int $time = 0): bool {
250 return $this->deleteByKey('', $key, $time);
254 * Add an item under a new key on a specific server
256 * @param string $server_key - The key identifying the server to store the value on
257 * or retrieve it from. Instead of hashing on the actual key for the item, we
258 * hash on the server key when deciding which memcached server to talk to.
259 * This allows related items to be grouped together on a single server for
260 * efficiency with multi operations..
261 * @param array $keys - The keys to be deleted.
262 * @param int $time - The amount of time the server will wait to delete
268 public function deleteMultiByKey(string $server_key, array $keys,
269 int $time = 0): mixed;
272 * Add an item under a new key on a specific server
274 * @param array $keys - The keys to be deleted.
275 * @param int $time - The amount of time the server will wait to delete
280 public function deleteMulti(array $keys, int $time = 0): mixed {
281 return $this->deleteMultiByKey('', $keys, $time);
285 * Delete an item from a specific server
287 * @param string $server_key -
288 * @param string $key - The key to be deleted.
289 * @param int $time - The amount of time the server will wait to delete
292 * @return bool - The Memcached::getResultCode will return
293 * Memcached::RES_NOTFOUND if the key does not exist.
296 public function deleteByKey(string $server_key,
298 int $time = 0): bool;
301 * Fetch the next result
303 * @return array - Returns the next result or FALSE otherwise. The
304 * Memcached::getResultCode will return Memcached::RES_END if result
308 public function fetch(): mixed;
311 * Fetch all the remaining results
313 * @return array - Returns the results.
316 public function fetchAll(): mixed;
319 * Invalidate all items in the cache
321 * @param int $delay - Numer of seconds to wait before invalidating the
327 public function flush(int $delay = 0): bool;
332 * @param string $key - The key of the item to retrieve.
333 * @param callable $cache_cb - Read-through caching callback or NULL.
334 * @param float $cas_token - The variable to store the CAS token in.
336 * @return mixed - Returns the value stored in the cache or FALSE
337 * otherwise. The Memcached::getResultCode will return
338 * Memcached::RES_NOTFOUND if the key does not exist.
340 public function get(mixed $key,
341 ?
mixed $cache_cb = null,
342 ?
mixed &$cas_token = null): mixed {
343 return $this->getByKey('', $key, $cache_cb, &$cas_token);
346 /* Memcached::getAllKeys() Gets the keys stored on all the servers
347 * @return mixed - Returns the keys stored on all the servers on success or
351 public function getAllKeys(): mixed;
354 * Retrieve an item from a specific server
356 * @param string $server_key -
357 * @param string $key - The key of the item to fetch.
358 * @param mixed $cache_cb - Read-through caching callback or NULL
359 * @param float $cas_token - The variable to store the CAS token in.
361 * @return mixed - Returns the value stored in the cache or FALSE
362 * otherwise. The Memcached::getResultCode will return
363 * Memcached::RES_NOTFOUND if the key does not exist.
366 public function getByKey(string $server_key,
368 mixed $cache_cb = null,
369 mixed &$cas_token = null): mixed;
372 * Request multiple items
374 * @param array $keys - Array of keys to request.
375 * @param bool $with_cas - Whether to request CAS token values also.
376 * @param callable $value_cb - The result callback or NULL.
380 public function getDelayed(mixed $keys,
381 mixed $with_cas = false,
382 mixed $value_cb = null): bool {
383 return $this->getDelayedByKey('', $keys, $with_cas, $value_cb);
387 * Request multiple items from a specific server
389 * @param string $server_key -
390 * @param array $keys - Array of keys to request.
391 * @param bool $with_cas - Whether to request CAS token values also.
392 * @param callable $value_cb - The result callback or NULL.
397 public function getDelayedByKey(string $server_key,
399 bool $with_cas = false,
400 ?callable
$value_cb = null): bool;
403 * Retrieve multiple items
405 * @param array $keys - Array of keys to retrieve.
406 * @param array $cas_tokens - The variable to store the CAS tokens for
408 * @param int $flags - The flags for the get operation.
410 * @return mixed - Returns the array of found items.
412 public function getMulti(mixed $keys,
413 mixed &$cas_tokens = null,
414 int $flags = 0): mixed {
415 return $this->getMultiByKey('', $keys, &$cas_tokens, $flags);
419 * Retrieve multiple items from a specific server
421 * @param string $server_key -
422 * @param array $keys - Array of keys to retrieve.
423 * @param string $cas_tokens - The variable to store the CAS tokens for
425 * @param int $flags - The flags for the get operation.
427 * @return array - Returns the array of found items.
430 public function getMultiByKey(string $server_key,
432 mixed &$cas_tokens = null,
433 int $flags = 0): mixed;
436 * Retrieve a Memcached option value
438 * @param int $option - One of the Memcached::OPT_* constants.
440 * @return mixed - Returns the value of the requested option, or FALSE
444 public function getOption(int $option): mixed;
447 * Return the result code of the last operation
449 * @return int - Result code of the last Memcached operation.
452 public function getResultCode(): int;
455 * Return the message describing the result of the last operation
457 * @return string - Message describing the result of the last Memcached
461 public function getResultMessage(): string;
464 * Map a key to a server
466 * @param string $server_key -
468 * @return array - Returns an array containing three keys of host,
469 * port, and weight on success or FALSE on failure.
472 public function getServerByKey(string $server_key): mixed;
475 * Get the list of the servers in the pool
477 * @return array - The list of all servers in the server pool.
480 public function getServerList(): array;
483 * Clears all server from the list
485 * @return bool - Returns TRUE on success or FALSE on failure.
488 public function resetServerList(): bool;
491 * Get server pool statistics
493 * @return array - Array of server statistics, one entry per server.
496 public function getStats(): mixed;
499 * Get server pool version info
501 * @return array - Array of server versions, one entry per server.
504 public function getVersion(): mixed;
507 * Increment numeric item's value
509 * @param string $key - The key of the item to increment.
510 * @param int $offset - The amount by which to increment the item's
512 * @param mixed $initial_value - The value to set the item to if it
513 * doesn't currently exist. False to fail if the key does not exist.
514 * @param int $expiry - The expiry time to set on the item.
516 * @return mixed - Returns new item's value on success. False if the key
520 public function increment(string $key,
522 mixed $initial_value = false,
523 int $expiry = 0): mixed;
526 * Increment numeric item's value, stored on a specific server
528 * @param string $server_key -
529 * @param string $key - The key of the item to increment.
530 * @param int $offset - The amount by which to increment the item's
532 * @param mixed $initial_value - The value to set the item to if it
533 * doesn't currently exist. False to fail if the key does not exist.
534 * @param int $expiry - The expiry time to set on the item.
536 * @return mixed - Returns new item's value on success. False if the key
537 * doesn't exist and no initial_value was provided.
540 public function incrementByKey(string $server_key,
543 mixed $initial_value = false,
544 int $expiry = 0): mixed;
547 * Check if a persitent connection to memcache is being used.
549 * @return bool - Returns true if Memcache instance uses a persistent
550 * connection, false otherwise.
553 public function isPersistent(): bool;
556 * Check if the instance was recently created
558 * @return bool - Returns the true if instance is recently created,
562 public function isPristine(): bool;
565 * Prepend data to an existing item
567 * @param string $key - The key of the item to prepend the data to.
568 * @param string $value - The string to prepend.
570 * @return bool - The Memcached::getResultCode will return
571 * Memcached::RES_NOTSTORED if the key does not exist.
573 public function prepend(mixed $key,
574 mixed $value): bool {
575 return $this->prependByKey('', $key, $value);
579 * Prepend data to an existing item on a specific server
581 * @param string $server_key -
582 * @param string $key - The key of the item to prepend the data to.
583 * @param string $value - The string to prepend.
585 * @return bool - The Memcached::getResultCode will return
586 * Memcached::RES_NOTSTORED if the key does not exist.
589 public function prependByKey(string $server_key,
591 string $value): bool;
594 * Memcached::quit() closes any open connections to the memcache servers.
595 * @return bool TRUE on success or FALSE on failure
598 public function quit(): bool;
601 * Replace the item under an existing key
603 * @param string $key -
604 * @param mixed $value -
605 * @param int $expiration -
607 * @return bool - The Memcached::getResultCode will return
608 * Memcached::RES_NOTSTORED if the key does not exist.
610 public function replace(mixed $key,
612 int $expiration = 0): bool {
613 return $this->replaceByKey('', $key, $value, $expiration);
617 * Replace the item under an existing key on a specific server
619 * @param string $server_key -
620 * @param string $key -
621 * @param mixed $value -
622 * @param int $expiration -
624 * @return bool - The Memcached::getResultCode will return
625 * Memcached::RES_NOTSTORED if the key does not exist.
628 public function replaceByKey(string $server_key,
631 int $expiration = 0): bool;
636 * @param string $key -
637 * @param mixed $value -
638 * @param int $expiration -
642 public function set(mixed $key,
644 int $expiration = 0): bool {
645 return $this->setByKey('', $key, $value, $expiration);
649 * Store an item on a specific server
651 * @param string $server_key -
652 * @param string $key -
653 * @param mixed $value -
654 * @param int $expiration -
659 public function setByKey(string $server_key,
662 int $expiration = 0): bool;
665 * Store multiple items
667 * @param array $items -
668 * @param int $expiration -
672 public function setMulti(array<string, mixed> $items,
673 int $expiration = 0): bool {
674 return $this->setMultiByKey('', $items, $expiration);
678 * Store multiple items on a specific server
680 * @param string $server_key -
681 * @param array $items -
682 * @param int $expiration -
686 public function setMultiByKey(string $server_key,
687 array<string, mixed> $items,
688 int $expiration = 0): bool {
689 foreach($items as $key => $value) {
691 // numeric strings (e.g. '5') become integers as array keys
693 } elseif (!is_string($key)) {
696 if (!$this->setByKey($server_key, $key, $value, $expiration)) {
704 * Set a Memcached option
706 * @param int $option -
707 * @param mixed $value -
712 public function setOption(int $option,
716 * Set Memcached options
718 * @param array $options -
722 public function setOptions(array<int, mixed> $options): bool {
723 foreach($options as $option => $value) {
724 if (!$this->setOption($option, $value)) {
732 * Set a new expiration on an item
734 * @param string $key - The key under which to store the value.
735 * @param int $expiration - The expiration time, defaults to 0.
737 * @return bool - Returns TRUE on success or FALSE on failure.
739 public function touch(string $key,
740 int $expiration = 0): bool {
741 return $this->touchByKey('', $key, $expiration);
745 * Set a new expiration on an item on a specific server
747 * @param string $server_key - The key identifying the server to store the
748 * value on or retrieve it from. Instead of hashing on the actual key for
749 * the item, we hash on the server key when deciding which memcached server
750 * to talk to. This allows related items to be grouped together on a single
751 * server for efficiency with multi operations.
752 * @param string $key - The key under which to store the value.
753 * @param int $expiration - The expiration time, defaults to 0.
755 * @return bool - Returns TRUE on success or FALSE on failure.
758 public function touchByKey(string $server_key,
760 int $expiration = 0): bool;
764 class MemcachedException
{
768 class MemcachedSessionModule
implements SessionHandlerInterface
{
770 const CONFIG_PERSISTENT
= 'PERSISTENT=';
773 private $persistentKey;
775 public function close() {
776 $this->memcached
= null;
777 $this->persistentKey
= null;
781 public function destroy($sessionId) {
782 $this->memcached
->delete($sessionId);
786 public function gc($maxLifetime) {
790 public function open($savePath, $name) {
791 $serverList = self
::parseSavePath($savePath);
796 $keyPrefix = trim((string)ini_get('memcached.sess_prefix'));
797 // Validate non-empty values (empty values are accepted)
798 if (strlen($keyPrefix) == 0 ||
799 strlen($keyPrefix) > 218 ||
800 !ctype_graph($keyPrefix)) {
801 trigger_error("Bad memcached key prefix in memcached.sess_prefix",
806 $memcached = new Memcached($this->persistentKey
);
807 foreach ($serverList as $serverInfo) {
808 $memcached->addServer($serverInfo['host'], $serverInfo['port']);
811 if (!$memcached->setOption(Memcached
::OPT_PREFIX_KEY
,
813 // setOption already throws a warning for bad values
817 $this->memcached
= $memcached;
822 public function read($sessionId) {
823 $data = $this->memcached
->get($sessionId);
825 // Return an empty string instead of false for new sessions as
826 // false values cause sessions to fail to init
832 public function write($sessionId, $data) {
833 return $this->memcached
->set($sessionId,
835 (int)ini_get('session.gc_maxlifetime'));
838 private static function parseSavePath($savePath) {
839 $savePath = trim($savePath);
840 if (empty($savePath)) {
841 trigger_error("Failed to initialize memcached session storage",
846 // Handle persistent key at front of save_path
847 if (strncasecmp($savePath,
848 self
::CONFIG_PERSISTENT
,
849 strlen(self
::CONFIG_PERSISTENT
)) === 0) {
850 $savePath = substr($savePath, strlen(self
::CONFIG_PERSISTENT
) - 1);
851 if (empty($savePath)) {
852 trigger_error("Invalid persistent id for session storage",
857 $explode = explode(' ', $savePath, 2);
858 if (count($explode) !== 2) {
859 trigger_error("Invalid persistent id for session storage",
864 $this->persistentKey
= $explode[0];
865 $savePath = $explode[1];
868 $serverList = explode(',', $savePath);
871 foreach ($serverList as $url) {
874 // Skip empty servers
878 $explode = explode(':', $url, 2);
880 $serverInfo = array('host' => $explode[0]);
882 // When port is missing (e.g. unix socket) use port of 0
883 $serverInfo['port'] = (isset($explode[1])) ?
(int)$explode[1] : 0;
885 $return[] = $serverInfo;