API Index — Namespaces, Packages, Reports, Indices
Counter
in package
Counter — backend-agnostic atomic integer.
Default backend is OpenSwoole\Atomic for lock-free cross-worker
sharing. Switch to Redis for cross-NODE atomicity:
Counter::defaultBackend('redis');
The instance API stays exactly as it was; existing new Counter(0)
call sites in the codebase keep working unchanged.
Usage:
$hits = new Counter(0);
$hits->increment(); // +1, returns new value
$hits->increment(5); // +5
$hits->compareAndSet(6, 0); // atomic CAS (Lua on Redis backend)
Table of Contents
Constants
- BACKEND_ATOMIC : mixed = 'atomic'
- BACKEND_MEMCACHED : mixed = 'memcached'
- BACKEND_REDIS : mixed = 'redis'
Properties
- $anonSerial : int
- Monotonically increasing serial for anonymous counter names.
- $backend : CounterBackend|null
-
$backendConfig
: array{kind: string, conn?: string|array
} - $name : string
Methods
- __construct() : mixed
- compareAndSet() : bool
- Compare-and-swap: if current value equals
$expected, set to$new. - decrement() : int
- Atomically subtract
$byand return the new value. - defaultBackend() : CounterBackend
- Get or set the process-wide default counter backend.
- expire() : bool
- Set TTL on the underlying key (N-3).
- get() : int
- Read the current value.
- increment() : int
- Atomically add
$byand return the new value. - incrementBounded() : int|null
- Bounded atomic increment (N-2). Increments only if the result would
stay within
$maxBound. Returns the new value, or NULL when the cap would be exceeded. - mincr() : array<string, int>
- Batch atomic increment (N-4). Pipelined on Redis (one round-trip for the whole batch); sequential on Atomic.
- raw() : Long
- Return the raw
OpenSwoole\Atomic\Long(64-bit signed). Only available on the atomic backend; throws on the redis backend (no atomic equivalent there). - reset() : void
- Reset to zero.
- set() : void
- Set the value (not atomic relative to concurrent add/sub).
- buildBackend() : CounterBackend
- memcachedServersFromEnv() : string
- poolOptsFromEnv() : array{prefer?: "auto"|"phpredis"|"predis"}
- redisUrlFromEnv() : string
Constants
BACKEND_ATOMIC
public
mixed
BACKEND_ATOMIC
= 'atomic'
BACKEND_MEMCACHED
public
mixed
BACKEND_MEMCACHED
= 'memcached'
BACKEND_REDIS
public
mixed
BACKEND_REDIS
= 'redis'
Properties
$anonSerial
Monotonically increasing serial for anonymous counter names.
private
static int
$anonSerial
= 0
spl_object_id() would reuse IDs after GC, leaking state between objects that happen to land on the same slot.
$backend
private
static CounterBackend|null
$backend
= null
$backendConfig
private
static array{kind: string, conn?: string|array}
$backendConfig
= ['kind' => 'atomic']
$name
private
string
$name
Methods
__construct()
public
__construct([int $initial = 0 ][, string|null $name = null ]) : mixed
Parameters
- $initial : int = 0
-
starting value (defaults to 0)
- $name : string|null = null
-
optional shared name; auto-generated unique when null
compareAndSet()
Compare-and-swap: if current value equals $expected, set to $new.
public
compareAndSet(int $expected, int $new) : bool
On the Redis backend this is one round-trip via a Lua script.
Parameters
- $expected : int
- $new : int
Return values
booldecrement()
Atomically subtract $by and return the new value.
public
decrement([int $by = 1 ]) : int
Parameters
- $by : int = 1
Return values
intdefaultBackend()
Get or set the process-wide default counter backend.
public
static defaultBackend([string|null $kind = null ][, string|array<string, mixed> $conn = [] ]) : CounterBackend
Parameters
- $kind : string|null = null
-
'atomic' (default) or 'redis'; null to read current
- $conn : string|array<string, mixed> = []
-
redis URL or ['url'=>, 'pool_size'=>, 'prefix'=>]
Return values
CounterBackendexpire()
Set TTL on the underlying key (N-3).
public
expire(int $seconds) : bool
Atomic backend: no-op, returns false. Shared memory has no TTL — the counter survives until the OpenSwoole master dies. Redis backend: applies EXPIRE on the counter's key. Returns true if the TTL was set; false if the key doesn't exist.
Parameters
- $seconds : int
Return values
boolget()
Read the current value.
public
get() : int
Return values
intincrement()
Atomically add $by and return the new value.
public
increment([int $by = 1 ]) : int
Parameters
- $by : int = 1
Return values
intincrementBounded()
Bounded atomic increment (N-2). Increments only if the result would
stay within $maxBound. Returns the new value, or NULL when the
cap would be exceeded.
public
incrementBounded([int $by = 1 ][, int $maxBound = PHP_INT_MAX ]) : int|null
$slots = new Counter(0, 'free_slots'); if ($slots->incrementBounded(1, 100) === null) { return 'pool full'; }
Parameters
- $by : int = 1
- $maxBound : int = PHP_INT_MAX
Return values
int|nullmincr()
Batch atomic increment (N-4). Pipelined on Redis (one round-trip for the whole batch); sequential on Atomic.
public
static mincr(array<string, int> $deltas) : array<string, int>
$hits = Counter::mincr(['page:home' => 1, 'page:about' => 1]); // ['page:home' => 142, 'page:about' => 87]
Parameters
- $deltas : array<string, int>
-
name → delta
Return values
array<string, int> —name → new value
raw()
Return the raw OpenSwoole\Atomic\Long (64-bit signed). Only available on
the atomic backend; throws on the redis backend (no atomic equivalent there).
public
raw() : Long
NOTE: as of the 64-bit-counter fix this returns OpenSwoole\Atomic\Long, not
the 32-bit OpenSwoole\Atomic it returned previously — so counters no longer
silently wrap at 2^32.
Return values
Longreset()
Reset to zero.
public
reset() : void
set()
Set the value (not atomic relative to concurrent add/sub).
public
set(int $value) : void
Parameters
- $value : int
buildBackend()
private
static buildBackend(array{kind: string, conn?: string|array} $cfg) : CounterBackend
Parameters
-
$cfg
: array{kind: string, conn?: string|array
}
Return values
CounterBackendmemcachedServersFromEnv()
private
static memcachedServersFromEnv() : string
Return values
stringpoolOptsFromEnv()
private
static poolOptsFromEnv() : array{prefer?: "auto"|"phpredis"|"predis"}
Return values
array{prefer?: "auto"|"phpredis"|"predis"}redisUrlFromEnv()
private
static redisUrlFromEnv() : string