Consumer
in package
php-amqplib blocking consume loop with HMAC verify-before-handler (CONTRACT.md §8, D-04).
This is NOT a web-request path — consume() blocks on $channel->wait()
for the lifetime of the process. It is meant to run on a long-running
runtime (a dedicated CLI worker process), restarted by a process
supervisor on exit (see bin/axiam-amqp-worker.php — no in-SDK
auto-reconnect loop, Pitfall 6).
Ack/nack semantics (verifyAndDispatch):
- HMAC verification failure -> nack WITHOUT requeue (fail closed, poison-loop risk)
- NEW-4 replay-protection gate failure -> nack WITHOUT requeue (fail closed, same as HMAC failure)
- Handler throws AmqpDropMessage -> nack WITHOUT requeue (application-declared poison message)
- Handler throws any other \Throwable -> nack WITH requeue (transient failure, retry)
- Handler completes successfully -> ack
NEW-4 (CONTRACT.md §8 "v2 — Replay Protection", hard cutover): once the
HMAC verifies, the delivery is ADDITIONALLY rejected (same nack-without-
requeue path) when key_version < 2, issued_at falls outside the
±skew freshness window, or nonce has already been seen. Because
Hmac::verify re-serializes the decoded body (minus hmac_signature) in
insertion order (Pitfall 5), nonce/issued_at are already covered by
the verified HMAC bytes with NO canonicalization change — only the
ReplayGuard gates are new. See ReplayGuard for the full policy.
Table of Contents
Methods
- __construct() : mixed
- consume() : void
- verifyAndDispatch() : void
- Verifies a single delivery's HMAC signature BEFORE the handler ever sees it (D-04), then applies the NEW-4 replay-protection gate, then maps the outcome to the ack/nack matrix documented on the class.
Methods
__construct()
public
__construct(string $signingKey[, LoggerInterface $logger = new NullLogger() ][, int $skewSeconds = ReplayGuard::DEFAULT_SKEW_SECONDS ][, ReplayGuard|null $replayGuard = null ]) : mixed
Parameters
- $signingKey : string
- $logger : LoggerInterface = new NullLogger()
- $skewSeconds : int = ReplayGuard::DEFAULT_SKEW_SECONDS
-
Freshness window (seconds) applied to a delivery's
issued_at(NEW-4); also sets the nonce dedup TTL (2×skewSeconds). Defaults to ReplayGuard::DEFAULT_SKEW_SECONDS (300s / 5 minutes), matching the server's DEFAULT_FRESHNESS_SKEW_SECS. Ignored when $replayGuard is supplied. - $replayGuard : ReplayGuard|null = null
-
Inject a preconfigured guard (e.g. with a fixed clock) for deterministic tests; when null a guard is constructed from $skewSeconds.
consume()
public
consume(string $host, int $port, string $user, string $pass, string $vhost, string $queue, callable(array<string, mixed>): void $handler) : void
Parameters
- $host : string
- $port : int
- $user : string
- $pass : string
- $vhost : string
- $queue : string
- $handler : callable(array<string, mixed>): void
-
Throws AmqpDropMessage for poison messages that must never be requeued.
verifyAndDispatch()
Verifies a single delivery's HMAC signature BEFORE the handler ever sees it (D-04), then applies the NEW-4 replay-protection gate, then maps the outcome to the ack/nack matrix documented on the class.
public
verifyAndDispatch(string $body, callable(array<string, mixed>): void $handler, callable(): mixed $ack, callable(): mixed $nackNoRequeue, callable(): mixed $nackRequeue) : void
Extracted from the basic_consume closure so it is a separately
testable unit — tests can drive it with fake ack/nack callables
without a live broker or AMQPMessage.
Parameters
- $body : string
- $handler : callable(array<string, mixed>): void
- $ack : callable(): mixed
- $nackNoRequeue : callable(): mixed
- $nackRequeue : callable(): mixed