evaneos/burrow-bundle
BurrowBundle packages evaneos/burrow, a PHP AMQP messaging library, for easy integration with Symfony Standard. It lets you publish and consume messages over AMQP with minimal setup, keeping queue configuration simple and idiomatic within a Symfony application.
evaneos/burrow-bundle is a thin Symfony integration for evaneos/burrow, an AMQP client built on top of php-amqplib. It does not give you a message bus, a serializer, or retries — it wires Burrow's Driver/Connection/Producer/Consumer primitives into the Symfony container. Treat it as a service-definition shim, not a framework.
Minimal setup:
composer require evaneos/burrow evaneos/burrow-bundle. Because the bundle is a wrapper, check which php-amqplib/php-amqplib version the pulled burrow release allows; this is the single most common source of install friction.Evaneos\BurrowBundle\BurrowBundle in config/bundles.php (this is a pre-AbstractBundle package, so the legacy registration is expected).config/packages/burrow.yaml with the broker connection: host, port, login, password, vhost. Confirm exact keys against src/DependencyInjection/Configuration.php — the README is one sentence long, so the source is the documentation.bin/console debug:container | grep -i burrow to see what actually got registered. Also read Resources/config/services.xml (or .yaml) to learn the real service IDs and aliases.First use case: publish a message. Inject the Burrow connection service into a small service, build a message with Burrow\Message/MessageBuilder, declare the exchange (or ensure it exists in your broker bootstrap), and publish. Don't start by writing a consumer — publishing validates config, credentials, vhost, and topology with almost no code.
Wrap producers in your own services. The bundle exposes the low-level connection; don't inject it across the app. Create App\Messaging\OrderProducer with a typed method (publish(OrderCreated $event)), inject the Burrow connection/driver, and let it own exchange names and routing keys. This keeps the bundle's service IDs out of your domain code and makes swapping later cheap.
Consumers as Symfony commands. Burrow's consumer is a blocking loop, so the standard Symfony pattern applies: a console command (app:consume:orders) that builds the consumer, calls consume(), and is supervised by Supervisor/systemd. Register the command in the container, tag it console.command, and pass queue/exchange names via command arguments or a --queue option rather than hardcoding.
Declare topology once, not per message. Exchange/queue/binding creation belongs in a deploy step or a small setup command, not in the hot publish path. If you declare per message you pay a round trip and risk channel errors; if you never declare you get confusing NOT_FOUND 404 errors when the broker is fresh.
Bridge from Symfony events/handlers. A common integration: a Doctrine or domain event listener dispatches to a MessageBusInterface-style interface that your producer implements. This keeps the bundle isolated to the infrastructure layer and lets tests use an in-memory bus.
Testing. Point your producer at a fake implementation of your own interface, or instantiate Burrow\MessageBuilder directly to assert body/headers/routing key without a broker. The Burrow driver interface is small enough to mock; RabbitMQ in CI via Docker is the alternative but slower.
Topology naming. Centralize exchange and queue names in one class/constant file so the publisher and consumer can't drift apart, since the bundle has no schema to enforce it.
composer.json, and be prepared to fork or replace with php-amqplib + Symfony Messenger if you need long-term support.Bundle class. If you're on Symfony 6+, verify the bundle still boots; a one-line getContainerExtension() bundle usually works, but deprecation noise is likely.Configuration.php defines scalar defaults (localhost, 5672, guest/guest, /), %env()% placeholders usually work for scalars, but arrays and booleans from env need a parameters indirection. Check before assuming RABBITMQ_URL style config.PhpAmqpLib\Exception\AMQPConnectionClosedException / AMQPIOException, reconnect, and restart the worker periodically (Supervisor stopwaitsecs, a --max-messages option). Memory growth from unbounded logging in the loop is the classic symptom.confirm_select/wait_for_pending_acks, or accept at-most-once and pair it with an outbox table.rabbitmqctl list_queues name messages consumers before reaching for PHP debuggers. Enable php-amqplib's debug/wire logging via the driver if the bundle exposes it; otherwise wrap the driver.Burrow\Driver and aliasing it in config/services.yaml — that's how you inject a test double or add structured logging. You can also override the bundle's service definitions by defining the same service ID in your app config (app definitions win in modern Symfony).DependencyInjection/Configuration.php and the service config files first; that's the actual API surface of this bundle.How can I help you explore Laravel packages today?