Language Support

AMQP PHP Client

The recommended PHP client is php-amqplib. It’s written in pure PHP, so there’s no C extension to compile, and it only needs the sockets and mbstring extensions. Install it with:

composer require php-amqplib/php-amqplib

Publish and consume

The example reads the broker URL from BROKER_URL and falls back to a local LavinMQ at amqp://guest:guest@localhost.

Save the connection helper as src/Amqp.php:

<?php

namespace Example;

use PhpAmqpLib\Connection\AbstractConnection;
use PhpAmqpLib\Connection\AMQPConnectionConfig;
use PhpAmqpLib\Connection\AMQPConnectionFactory;

final class Amqp
{
    // Connects to BROKER_URL, e.g. amqps://user:password@host/vhost
    public static function connect(): AbstractConnection
    {
        return AMQPConnectionFactory::create(self::config(getenv('BROKER_URL') ?: 'amqp://guest:guest@localhost'));
    }

    // rawurldecode, not urldecode, so a literal "+" in a password is kept
    public static function config(string $amqpUrl): AMQPConnectionConfig
    {
        $url = parse_url($amqpUrl);
        $secure = $url['scheme'] === 'amqps';

        $config = new AMQPConnectionConfig();
        $config->setHost($url['host']);
        $config->setPort($url['port'] ?? ($secure ? 5671 : 5672));
        $config->setUser(rawurldecode($url['user'] ?? 'guest'));
        $config->setPassword(rawurldecode($url['pass'] ?? 'guest'));
        $config->setVhost(rawurldecode(ltrim($url['path'] ?? '', '/')) ?: '/');
        $config->setIsSecure($secure);

        return $config;
    }
}

Save the publisher as src/Publisher.php:

<?php

namespace Example;

use PhpAmqpLib\Channel\AMQPChannel;
use PhpAmqpLib\Message\AMQPMessage;

final class Publisher
{
    // Waits until the broker has confirmed the message
    public static function publish(AMQPChannel $channel, string $queue, string $message): void
    {
        $channel->queue_declare($queue, false, true, false, false);
        $channel->confirm_select();
        $channel->basic_publish(new AMQPMessage($message, [
            'content_type' => 'text/plain',
            'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT,
        ]), '', $queue);
        $channel->wait_for_pending_acks(5);
        echo " [x] Sent '$message'\n";
    }
}

Save the consumer as src/Worker.php:

<?php

namespace Example;

use PhpAmqpLib\Channel\AMQPChannel;
use PhpAmqpLib\Message\AMQPMessage;

final class Worker
{
    // The message is acked after the handler has processed it
    public static function consume(AMQPChannel $channel, string $queue, callable $handler): void
    {
        $channel->queue_declare($queue, false, true, false, false);
        $channel->basic_qos(0, 10, false);
        $channel->basic_consume($queue, '', false, false, false, false, function (AMQPMessage $msg) use ($handler) {
            $handler($msg->getBody());
            $msg->ack();
        });
    }
}

Save the publisher script as publisher.php in the project root:

<?php

require __DIR__ . '/vendor/autoload.php';

use Example\Amqp;
use Example\Publisher;

$connection = Amqp::connect();
Publisher::publish($connection->channel(), 'hello', 'Hello world!');
$connection->close();

Save the worker script as worker.php next to it:

<?php

require __DIR__ . '/vendor/autoload.php';

use Example\Amqp;
use Example\Worker;

$connection = Amqp::connect();
$channel = $connection->channel();
Worker::consume($channel, 'hello', function (string $message) {
    echo " [x] Received '$message'\n";
});
echo " [*] Waiting for messages. To exit press CTRL+C\n";
$channel->consume();

The composer.json that autoloads the Example namespace from src/ lives in the example repo. Run composer install, then php worker.php in one terminal and php publisher.php in another.

The full, runnable example lives in php/php-amqplib in cloudamqp/examples, and CI tests it against LavinMQ.

Good to know

  • Acks are manual. The worker calls $msg->ack() after the handler returns. If the handler throws, the exception escapes consume() and the message stays unacked, so LavinMQ requeues it once the connection closes. Keep handlers idempotent.
  • Set a prefetch limit. basic_qos defaults to a prefetch of 0, which means unlimited. The example sets 10 with basic_qos(0, 10, false).
  • There’s no automatic recovery. A dropped connection throws an exception, and reconnect() doesn’t recreate channels or consumers. Catch the exception, open a new connection and set up the consumer again.
  • Use amqps:// for TLS. The example turns on TLS for amqps:// URLs. php-amqplib leaves certificate checks to PHP’s defaults, which verify the server certificate and hostname.

The php-amqplib README covers connection recovery, batch publishing and signal-based heartbeats.

Other PHP clients

  • PECL AMQP, a C extension built on librabbitmq
  • Bunny, a client with both synchronous and async (ReactPHP) APIs

Ready to take the next steps?

Managed LavinMQ instance via CloudAMQP

LavinMQ has been built with performance and ease of use in mind - we've benchmarked a throughput of about 1,000,000 messages/sec. You can try LavinMQ without any installation hassle by creating a free instance on CloudAMQP. Signing up is a breeze.

Get started with CloudAMQP ->

Help and feedback

We welcome your feedback and are eager to address any questions you may have about this piece or using LavinMQ. Join our Slack channel to connect with us directly. You can also find LavinMQ on GitHub.


Can’t find what you’re looking for? Let us know
Was this helpful?

Search