Alpha ZealPHP is early-stage and under active development. APIs may change between minor versions until v1.0. Feedback and bug reports welcome on GitHub.
API Index — Namespaces, Packages, Reports, Indices

MemcachedCounterBackend
in package
implements CounterBackend

FinalYes

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 increment won't create a key; we initialize lazily via add which 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

$client  : Memcached
$prefix  : string

Methods

__construct()  : mixed
compareAndSet()  : bool
Atomically compare-and-swap counter $name using Memcached::gets() + cas().
decr()  : int
Atomically decrement counter $name by $by and return the new value.
expire()  : bool
Set a TTL of $seconds on counter $name via Memcached::touch().
get()  : int
Return the current integer value of counter $name, or 0 if the key does not exist.
incr()  : int
Atomically increment counter $name by $by and return the new value.
incrBounded()  : int|null
Increment $name by $by only 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 $name to 0. Creates the key if it does not exist.
set()  : bool
Unconditionally set counter $name to $value. Returns true on success.
setIfAbsent()  : bool
Set counter $name to $value only when the key does not already exist (Memcached::add() SETNX semantics). Returns false when the key already exists.
key()  : string
Build the namespaced Memcached key for counter $name using the configured $prefix.
parseServers()  : array<int, array{0: string, 1: int}>

Properties

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
bool

decr()

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
int

expire()

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
bool

get()

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
int

incr()

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
int

incrBounded()

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|null

mincr()

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
bool

setIfAbsent()

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
bool

key()

Build the namespaced Memcached key for counter $name using the configured $prefix.

private key(string $name) : string
Parameters
$name : string
Return values
string

parseServers()

private static parseServers(string $servers) : array<int, array{0: string, 1: int}>
Parameters
$servers : string
Return values
array<int, array{0: string, 1: int}>
On this page