API Index — Namespaces, Packages, Reports, Indices
MemcachedCounterBackend
in package
implements
CounterBackend
Memcached-backed CounterBackend.
Memcached has native atomic increment / decrement that operate
server-side on integer values — cross-node atomic without the round-
trip cost of Redis Lua. Compare-and-swap uses the gets + cas pair.
Trade-offs vs. Redis:
- No TTL on counter keys via this API (Memcached
incrementwon't create a key; we initialize lazily viaaddwhich DOES respect TTL — but only on first creation).expire()is a no-op here. - No native batch increment (mincr loops sequentially).
- No native bounded-increment (Lua-on-Redis is the only way to get atomic check-then-increment); incrBounded is implemented as a CAS retry loop, bounded at 100 attempts under contention.
Use case: cross-server counters where Memcached is the established shared-cache infrastructure and a Redis dependency is undesired.
Table of Contents
Interfaces
- CounterBackend
- Behavioural contract for Counter backends.
Properties
Methods
- __construct() : mixed
- compareAndSet() : bool
- Atomically compare-and-swap counter
$nameusingMemcached::gets()+cas(). - decr() : int
- Atomically decrement counter
$nameby$byand return the new value. - expire() : bool
- Set a TTL of
$secondson counter$nameviaMemcached::touch(). - get() : int
- Return the current integer value of counter
$name, or0if the key does not exist. - incr() : int
- Atomically increment counter
$nameby$byand return the new value. - incrBounded() : int|null
- Increment
$nameby$byonly when the result would not exceed$maxBound. - mincr() : array<string, int>
- Increment multiple counters sequentially. Memcached has no native multi-increment; for high-throughput bulk increments prefer the Redis backend.
- reset() : void
- Reset counter
$nameto0. Creates the key if it does not exist. - set() : bool
- Unconditionally set counter
$nameto$value. Returnstrueon success. - setIfAbsent() : bool
- Set counter
$nameto$valueonly when the key does not already exist (Memcached::add()SETNX semantics). Returnsfalsewhen the key already exists. - key() : string
- Build the namespaced Memcached key for counter
$nameusing the configured$prefix. - parseServers() : array<int, array{0: string, 1: int}>
Properties
$client
private
Memcached
$client
$prefix
private
string
$prefix
= 'zealstore'
Methods
__construct()
public
__construct([string $servers = '127.0.0.1:11211' ][, string $prefix = 'zealstore' ]) : mixed
Parameters
- $servers : string = '127.0.0.1:11211'
-
comma-separated host[:port] list
- $prefix : string = 'zealstore'
compareAndSet()
Atomically compare-and-swap counter $name using Memcached::gets() + cas().
public
compareAndSet(string $name, int $expected, int $new) : bool
Returns false when the current value differs from $expected or the CAS token race is lost.
Parameters
- $name : string
- $expected : int
- $new : int
Return values
booldecr()
Atomically decrement counter $name by $by and return the new value.
public
decr(string $name[, int $by = 1 ]) : int
Lazily initialises the key to 0 on first call (same two-round-trip cold path as incr()).
Parameters
- $name : string
- $by : int = 1
Return values
intexpire()
Set a TTL of $seconds on counter $name via Memcached::touch().
public
expire(string $name, int $seconds) : bool
Returns false when the key does not exist. Note: incr()/decr() do not
accept a TTL parameter in the Memcached protocol, so TTL applies only on first creation.
Parameters
- $name : string
- $seconds : int
Return values
boolget()
Return the current integer value of counter $name, or 0 if the key does not exist.
public
get(string $name) : int
Parameters
- $name : string
Return values
intincr()
Atomically increment counter $name by $by and return the new value.
public
incr(string $name[, int $by = 1 ]) : int
Lazily initialises the key to 0 on first call (two round-trips cold, one hot).
Parameters
- $name : string
- $by : int = 1
Return values
intincrBounded()
Increment $name by $by only when the result would not exceed $maxBound.
public
incrBounded(string $name, int $by, int $maxBound) : int|null
Implemented as a CAS retry loop (max 100 attempts). Returns the new value, or
null when the bound would be exceeded or contention exhausted all attempts.
Parameters
- $name : string
- $by : int
- $maxBound : int
Return values
int|nullmincr()
Increment multiple counters sequentially. Memcached has no native multi-increment; for high-throughput bulk increments prefer the Redis backend.
public
mincr(array<string, int> $deltas) : array<string, int>
Parameters
- $deltas : array<string, int>
-
Counter name → increment amount.
Return values
array<string, int> —Counter name → new value after increment.
reset()
Reset counter $name to 0. Creates the key if it does not exist.
public
reset(string $name) : void
Parameters
- $name : string
set()
Unconditionally set counter $name to $value. Returns true on success.
public
set(string $name, int $value) : bool
Parameters
- $name : string
- $value : int
Return values
boolsetIfAbsent()
Set counter $name to $value only when the key does not already exist
(Memcached::add() SETNX semantics). Returns false when the key already exists.
public
setIfAbsent(string $name, int $value) : bool
Parameters
- $name : string
- $value : int
Return values
boolkey()
Build the namespaced Memcached key for counter $name using the configured $prefix.
private
key(string $name) : string
Parameters
- $name : string
Return values
stringparseServers()
private
static parseServers(string $servers) : array<int, array{0: string, 1: int}>
Parameters
- $servers : string