Introduction

babelqueue/php-sdk is the framework-agnostic PHP core: the wire-envelope codec, contracts, validation and dead-letter helpers. It is the single PHP implementation of the wire format, so the framework adapters reuse it and can never drift.

Most PHP applications don’t install this directly — they install an adapter, which pulls the core in:

  • Laravel — a drop-in polyglot queue driver.
  • Symfony — a Messenger serializer.

Install the core directly only for a framework-less PHP app, or to build a new adapter.

What you get

  • EnvelopeCodec — build (make / fromJob), encode, decode, urn and accepts for the canonical {job, trace_id, data, meta, attempts} envelope (schema_version: 1).
  • ContractsPolyglotJob (getBabelUrn() + toPayload()), HasTraceId, InboundMessage, ConsumedMessage, and a minimal Transport seam.
  • ValidationEnvelopeValidator (consumer-side checks with a reason, so you can quarantine an unsupported schema_version instead of dropping it) and the offline SchemaValidator (validate any envelope against the bundled canonical JSON Schema).
  • Reference transports — optional framework-less producers for all seven brokers: RedisTransport, AmqpTransport, SqsTransport, plus KafkaTransport (§6), PulsarTransport (§5) and StompTransport (§7, Artemis).
  • Framework-less consumersKafkaConsumer (§6 over ext-rdkafka, process-then-commit) and PulsarConsumer (§5 over Pulsar’s WebSocket API), plus the §6.4/§6.5 Kafka retry-topic machinery (KafkaRetryRouter + KafkaRetryConsumer).
  • A consume runtimeConsume\Dispatcher (URN → handler routing + the four on_unknown_urn strategies) and Consume\DeadLetterPublisher (route poison messages to <queue>.dlq).
  • Dead-letter + unknown-URN strategies, and a dependency-free UUIDv4.

Zero heavy dependencies — PHP ^8.2 and ext-json only; each transport’s broker client is an opt-in suggestion you install only when you use it.

Core, not a full framework worker

This core is the contract runtime plus optional building blocks — the codec, the transports and the framework-less consume primitives above. It deliberately has no long-running supervisor, backoff scheduler or process manager: on Laravel and Symfony you bind to the framework’s native queue (the drop-in driver, Messenger) and reuse that framework’s worker and retry; for a framework-less service, the KafkaConsumer / PulsarConsumer consume() loops + the Dispatcher give you a complete consume path on those brokers.

The envelope

{
  "job": "urn:babel:orders:created",
  "trace_id": "7b3f9c2a-e41d-4f88-9b2a-1c0d5e6f7a8b",
  "data": { "order_id": 1042 },
  "meta": { "id": "f1e2d3c4-b5a6-4789-90ab-cdef01234567", "queue": "orders", "lang": "php", "schema_version": 1, "created_at": 1749132727000 },
  "attempts": 0
}

See the full wire contract. Continue to Installation.