99 lines
3.4 KiB
PHP
99 lines
3.4 KiB
PHP
<?php
|
|
// MemcachedProviderLegacy.php
|
|
// Created: 2024-04-10
|
|
// Updated: 2024-04-10
|
|
|
|
namespace Index\Cache\Memcached;
|
|
|
|
use InvalidArgumentException;
|
|
use Memcache;
|
|
use Index\Net\{DnsEndPoint,IPEndPoint,UnixEndPoint};
|
|
|
|
/**
|
|
* Legacy Memcached provider implementation.
|
|
*/
|
|
class MemcachedProviderLegacy extends MemcachedProvider {
|
|
private Memcache $memcache;
|
|
private string $prefix;
|
|
private bool $persistent;
|
|
private bool $compress;
|
|
|
|
public function __construct(MemcachedProviderInfo $providerInfo) {
|
|
$this->prefix = $providerInfo->getPrefixKey();
|
|
$this->compress = $providerInfo->shouldEnableCompression();
|
|
$this->persistent = $providerInfo->isPersistent();
|
|
$this->memcache = new Memcache;
|
|
|
|
foreach($providerInfo->getEndPoints() as $endPointInfo) {
|
|
if($endPointInfo[0] instanceof UnixEndPoint) {
|
|
$host = 'unix://' . $endPointInfo[0]->getPath();
|
|
$port = 0;
|
|
} elseif($endPointInfo[0] instanceof DnsEndPoint) {
|
|
$host = $endPointInfo[0]->getHost();
|
|
$port = $endPointInfo[0]->getPort();
|
|
} elseif($endPointInfo[0] instanceof IPEndPoint) {
|
|
$host = $endPointInfo[0]->getAddress()->getCleanAddress();
|
|
$port = $endPointInfo[0]->getPort();
|
|
} else throw new InvalidArgumentException('One of the servers specified in $providerInfo is not a supported endpoint.');
|
|
|
|
$this->memcache->addServer($host, $port, $this->persistent, $endPointInfo[1]);
|
|
}
|
|
}
|
|
|
|
public function get(string $key): mixed {
|
|
$value = $this->memcache->get($this->prefix . $key);
|
|
return $value === false ? null : unserialize($value);
|
|
}
|
|
|
|
public function set(string $key, mixed $value, int $ttl = 0): void {
|
|
if($ttl < 0)
|
|
throw new InvalidArgumentException('$ttl must be equal to or greater than 0.');
|
|
if($ttl > MemcachedProvider::MAX_TTL)
|
|
throw new InvalidArgumentException('$ttl may not be greater than 30 days.');
|
|
if($value === null)
|
|
return;
|
|
|
|
$serialised = serialize($value);
|
|
$flags = 0;
|
|
if($this->compress && strlen($serialised) > 100)
|
|
$flags |= MEMCACHE_COMPRESSED;
|
|
|
|
$this->memcache->set($this->prefix . $key, $serialised, $flags, $ttl);
|
|
}
|
|
|
|
public function delete(string $key): void {
|
|
$this->memcache->delete($this->prefix . $key);
|
|
}
|
|
|
|
public function touch(string $key, int $ttl = 0): void {
|
|
$this->set($key, $this->get($key), $ttl);
|
|
}
|
|
|
|
public function increment(string $key, int $amount = 1): int {
|
|
$key = $this->prefix . $key;
|
|
$result = $this->memcache->increment($key, $amount);
|
|
if($result === false) { // @phpstan-ignore-line: PHP documentation states increment returns int|false
|
|
$result = $amount;
|
|
$this->memcache->set($key, serialize($result), 0);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function decrement(string $key, int $amount = 1): int {
|
|
$key = $this->prefix . $key;
|
|
$result = $this->memcache->decrement($key, $amount);
|
|
if($result === false) { // @phpstan-ignore-line: PHP documentation states decrement returns int|false
|
|
$result = $amount * -1;
|
|
$this->memcache->set($key, serialize($result), 0);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function close(): void {
|
|
if(!$this->persistent)
|
|
$this->memcache->close();
|
|
}
|
|
}
|