index/src/Cache/Memcached/MemcachedProviderLegacy.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();
}
}