PHP collector API
seamward/php-collector is the framework-neutral implementation shared by PHP adapters. It targets PHP 8.3 or later, has no framework dependency, and is available from Packagist as an alpha package.
Connection and policy
Connection::fromCredentials($connectionKey, $ingestToken, $endpoint) validates both Integration-owned values, derives the bound Integration id, and requires HTTPS except for localhost development.
RedactionPolicy accepts:
| Argument | Default | Purpose |
|---|---|---|
version | shape-only-v1 | Audit label stored with every payload shape |
hashKey | collector-derived | Local key used before identifiers enter an envelope |
hashNamespace | deterministic local derivation | Non-secret generation label for keyed hashes |
dropFields | [] | Fields removed by the optional local payload redaction helper |
hashFields | [] | Fields hashed by the optional local payload redaction helper |
The default hash key is derived locally from the ingest token and the token itself is never serialized into an envelope.
Observations
Create an Observation with an Operation, status code, duration, and JSON-compatible payload. Convenience factories cover inbound webhooks and outbound HTTP APIs:
Code example
Operation::inboundWebhook('/webhooks/candidates');Operation::outboundHttp('POST', '/v1/candidates');Operation::queuePublish('candidate-events');Operation::queueConsume('candidate-events');Operation::scheduledFeed('nightly-candidate-import', 'inbound');HTTP route templates must be bounded absolute paths without a query string. Surrounding whitespace is trimmed, and :id or {id} segments are normalized to {}. Queue and scheduled-feed targets use bounded stable labels. Use placeholders rather than concrete identifiers. JsonValue::decode() preserves the difference between JSON objects and arrays, including empty {}, [], and numeric-string object keys.
Optional observation metadata includes attempt, eventType, declaredContractVersion, deployment, correlation, and outcome. Raw correlation identifiers and business object ids are replaced by keyed hashes.
The completed envelope is validated strictly before enqueue. Unknown fields, invalid nested values, malformed deployment labels, noncanonical keyed hashes, missing operation identity, invalid status combinations, and malformed shapes are rejected locally. record() suppresses that telemetry failure and increments buildErrors.
Collector lifecycle
Collector::connect() accepts a validated connection, a transport, and optional buffer, policy, envelope builder, and batch size.
record(Observation $observation): voidbuilds and buffers an envelope. It never throws.observeQueuePublish(...)wraps an outbound queue publisher and projects success, rejection, or error to202,422, or500.observeQueueConsumer(...)wraps an inbound queue consumer with the same status projection.observeScheduledFeed(...)wraps an inbound import or outbound export and projects completion, rejection, or error to200,422, or500.flush(): voidships the current queue. It never throws.stats(): arrayreturns seven delivery and build counters.
The default in-memory buffer holds 1,000 envelopes and drops the oldest entry on overflow. The default batch size is 50.
Collector::connect() also accepts deployment. Explicit valid values win over supported environment variables. A valid deployment attached directly to one Observation wins over the collector default. The core remains manual-flush by design and performs no destructor or timer-based network I/O.
Local redaction helpers
Redactor::payload($value, $policy) and Redactor::headers($headers, $policy) mirror the Node.js helpers for separate local logging or storage pipelines. Credential headers are always dropped. These helpers do not provide the envelope privacy boundary; payload values and headers cannot enter an envelope regardless.
Transport contract
Implement Seamward\Collector\Transport\Transport:
Code example
interface Transport{ public function send(ShippingRequest $request): ShippingResponse;}The request contains endpoint, headers, and the exact JSON body covered by X-Seamward-Signature. Return the HTTP status and body as a ShippingResponse. Transport exceptions are caught by the collector.
Failure behavior
| Result | Queue behavior | Counter |
|---|---|---|
2xx except 207 | Remove the batch | shipped |
Valid 207 | Remove the batch and account per result | shipped and rejected |
Non-retryable 4xx | Remove the batch | rejected |
409, 429, 5xx, transport error, malformed 207 | Retain the batch | failedBatches |
| Buffer overflow | Drop oldest | dropped |
| Invalid observation | Do not enqueue | buildErrors |
