CloudAMQP with PHP
We recommend php-amqplib, a pure
PHP client. It needs the sockets and mbstring extensions.
composer require php-amqplib/php-amqplib
Publish and consume
Set CLOUDAMQP_URL to the AMQP URL from your instance’s details page in the
CloudAMQP console. Without it, the examples connect to a local broker.
The classes live in src/ under the Example namespace. Add this to
composer.json and run composer dump-autoload:
"autoload": {
"psr-4": { "Example\\": "src/" }
}
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 CLOUDAMQP_URL, e.g. amqps://user:password@host/vhost
public static function connect(): AbstractConnection
{
return AMQPConnectionFactory::create(self::config(getenv('CLOUDAMQP_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;
}
}
Use percent-encoding for special characters in credentials and the virtual
host (for example, %2F for the default / virtual host).
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 entry point as publisher.php:
<?php
require __DIR__ . '/vendor/autoload.php';
use Example\Amqp;
use Example\Publisher;
$connection = Amqp::connect();
Publisher::publish($connection->channel(), 'hello', 'Hello CloudAMQP!');
$connection->close();
Save the consumer entry point as worker.php. Worker::consume registers
the callback; the channel’s consume method runs the event loop:
<?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();
Run php worker.php in one terminal and php publisher.php in another.
A runnable example is in php/php-amqplib in cloudamqp/examples.
Good to know
- Connect with the URL. php-amqplib doesn’t parse URLs, so the example
builds an
AMQPConnectionConfigfrom the URL on your instance’s details page in the CloudAMQP console, withsetIsSecure(true)foramqps://. PHP verifies the server certificate by default. - php-amqplib doesn’t reconnect. Let your process manager restart a worker whose connection is lost.
- Use publisher confirms (
confirm_select,wait_for_pending_acks) and persistent messages, so a message isn’t lost if the connection or broker goes down. - Ack after processing, and set a prefetch limit with
basic_qos, so a consumer doesn’t buffer more messages than it can handle.
Other PHP libraries
- PECL AMQP, an extension built on the RabbitMQ C client