con = new \Memcached(); $this->connect($data); } /** * Connect to cache * * @param null|array{host:string, port:int} $data Cache data * * @return void * * @since 1.0.0 */ public function connect(array $data = null) : void { $this->dbdata = isset($data) ? $data : $this->dbdata; if (!isset($this->dbdata['host'], $this->dbdata['port'])) { $this->status = CacheStatus::FAILURE; throw new InvalidConnectionConfigException((string) \json_encode($this->dbdata)); } $this->con->addServer($this->dbdata['host'], $this->dbdata['port']); $this->status = CacheStatus::OK; } /** * {@inheritdoc} */ public function set(int|string $key, mixed $value, int $expire = -1) : void { if ($this->status !== CacheStatus::OK) { return; } if (!(\is_scalar($value) || $value === null || \is_array($value) || $value instanceof \JsonSerializable || $value instanceof \Serializable)) { throw new \InvalidArgumentException(); } $this->con->set($key, $value, \max($expire, 0)); } /** * {@inheritdoc} */ public function add(int|string $key, mixed $value, int $expire = -1) : bool { if ($this->status !== CacheStatus::OK) { return false; } if (!(\is_scalar($value) || $value === null || \is_array($value) || $value instanceof \JsonSerializable || $value instanceof \Serializable)) { throw new \InvalidArgumentException(); } return $this->con->add($key, $value, \max($expire, 0)); } /** * {@inheritdoc} */ public function get(int|string $key, int $expire = -1) : mixed { if ($this->status !== CacheStatus::OK) { return null; } $result = $this->con->get($key); if ($this->con->getResultCode() !== \Memcached::RES_SUCCESS) { return null; } return $result; } /** * {@inheritdoc} */ public function delete(int|string $key, int $expire = -1) : bool { if ($this->status !== CacheStatus::OK) { return false; } return $this->con->delete($key); } /** * {@inheritdoc} */ public function exists(int|string $key, int $expire = -1) : bool { if ($this->status !== CacheStatus::OK) { return false; } return $this->con->get($key) !== false; } /** * {@inheritdoc} */ public function increment(int|string $key, int $value = 1) : void { $this->con->increment($key, $value); } /** * {@inheritdoc} */ public function decrement(int|string $key, int $value = 1) : void { $this->con->decrement($key, $value); } /** * {@inheritdoc} */ public function rename(int|string $old, int|string $new, int $expire = -1) : void { $value = $this->get($old); $this->set($new, $value, $expire); $this->delete($old); } /** * {@inheritdoc} */ public function getLike(string $pattern, int $expire = -1) : array { if ($this->status !== CacheStatus::OK) { return []; } $keys = $this->con->getAllKeys(); $values = []; foreach ($keys as $key) { if (\preg_match('/' . $pattern . '/', $key) === 1) { $result = $this->con->get($key); if (\is_string($result)) { $type = (int) $result[0]; $start = (int) \strpos($result, self::DELIM); $result = $this->reverseValue($type, $result, $start); } $values[] = $result; } } return $values; } /** * {@inheritdoc} */ public function deleteLike(string $pattern, int $expire = -1) : bool { if ($this->status !== CacheStatus::OK) { return false; } $keys = $this->con->getAllKeys(); foreach ($keys as $key) { if (\preg_match('/' . $pattern . '/', $key) === 1) { $this->con->delete($key); } } return true; } /** * {@inheritdoc} */ public function updateExpire(int|string $key, int $expire = -1) : bool { if ($expire > 0) { $this->con->touch($key, $expire); } return true; } /** * {@inheritdoc} */ public function flush(int $expire = 0) : bool { return $this->flushAll(); } /** * {@inheritdoc} */ public function flushAll() : bool { if ($this->status !== CacheStatus::OK) { return false; } $this->con->flush(); return true; } /** * {@inheritdoc} */ public function replace(int|string $key, mixed $value, int $expire = -1) : bool { if ($this->status !== CacheStatus::OK) { return false; } return $this->con->replace($key, $value, \max($expire, 0)); } /** * {@inheritdoc} */ public function stats() : array { if ($this->status !== CacheStatus::OK) { return []; } $stat = $this->con->getStats(); $temp = \reset($stat); $stats = []; $stats['status'] = $this->status; $stats['count'] = $temp['curr_items']; $stats['size'] = $temp['bytes']; return $stats; } /** * {@inheritdoc} */ public function getThreshold() : int { return $this->threshold; } /** * Destructor. * * @since 1.0.0 */ public function __destruct() { $this->close(); } /** * Closing cache. * * @return void * * @since 1.0.0 */ public function close() : void { if ($this->con !== null) { $this->con->quit(); } parent::close(); } }