The most widely used PHP client for RabbitMQ

Overview

php-amqplib

PHPUnit tests Latest Version on Packagist Total Downloads Software License

codecov Coverage Status Quality Score

This library is a pure PHP implementation of the AMQP 0-9-1 protocol. It's been tested against RabbitMQ.

The library was used for the PHP examples of RabbitMQ in Action and the official RabbitMQ tutorials.

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

Project Maintainers

Thanks to videlalvaro and postalservice14 for creating php-amqplib.

The package is now maintained by Ramūnas Dronga, Luke Bakken and several VMware engineers working on RabbitMQ.

Supported RabbitMQ Versions

Starting with version 2.0 this library uses AMQP 0.9.1 by default and thus requires RabbitMQ 2.0 or later version. Usually server upgrades do not require any application code changes since the protocol changes very infrequently but please conduct your own testing before upgrading.

Supported RabbitMQ Extensions

Since the library uses AMQP 0.9.1 we added support for the following RabbitMQ extensions:

  • Exchange to Exchange Bindings
  • Basic Nack
  • Publisher Confirms
  • Consumer Cancel Notify

Extensions that modify existing methods like alternate exchanges are also supported.

Related libraries

  • enqueue/amqp-lib is a amqp interop compatible wrapper.

  • AMQProxy is a proxy library with connection and channel pooling/reusing. This allows for lower connection and channel churn when using php-amqplib, leading to less CPU usage of RabbitMQ.

Setup

Ensure you have composer installed, then run the following command:

$ composer require php-amqplib/php-amqplib

That will fetch the library and its dependencies inside your vendor folder. Then you can add the following to your .php files in order to use the library

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

Then you need to use the relevant classes, for example:

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

Usage

With RabbitMQ running open two Terminals and on the first one execute the following commands to start the consumer:

$ cd php-amqplib/demo
$ php amqp_consumer.php

Then on the other Terminal do:

$ cd php-amqplib/demo
$ php amqp_publisher.php some text to publish

You should see the message arriving to the process on the other Terminal

Then to stop the consumer, send to it the quit message:

$ php amqp_publisher.php quit

If you need to listen to the sockets used to connect to RabbitMQ then see the example in the non blocking consumer.

$ php amqp_consumer_non_blocking.php

Change log

Please see CHANGELOG for more information what has changed recently.

API Documentation

http://php-amqplib.github.io/php-amqplib/

Tutorials

To not repeat ourselves, if you want to learn more about this library, please refer to the official RabbitMQ tutorials.

More Examples

  • amqp_ha_consumer.php: demos the use of mirrored queues.
  • amqp_consumer_exclusive.php and amqp_publisher_exclusive.php: demos fanout exchanges using exclusive queues.
  • amqp_consumer_fanout_{1,2}.php and amqp_publisher_fanout.php: demos fanout exchanges with named queues.
  • amqp_consumer_pcntl_heartbeat.php: demos signal-based heartbeat sender usage.
  • basic_get.php: demos obtaining messages from the queues by using the basic get AMQP call.

Multiple hosts connections

If you have a cluster of multiple nodes to which your application can connect, you can start a connection with an array of hosts. To do that you should use the create_connection static method.

For example:

$connection = AMQPStreamConnection::create_connection([
    ['host' => HOST1, 'port' => PORT, 'user' => USER, 'password' => PASS, 'vhost' => VHOST],
    ['host' => HOST2, 'port' => PORT, 'user' => USER, 'password' => PASS, 'vhost' => VHOST]
],
$options);

This code will try to connect to HOST1 first, and connect to HOST2 if the first connection fails. The method returns a connection object for the first successful connection. Should all connections fail it will throw the exception from the last connection attempt.

See demo/amqp_connect_multiple_hosts.php for more examples.

Batch Publishing

Let's say you have a process that generates a bunch of messages that are going to be published to the same exchange using the same routing_key and options like mandatory. Then you could make use of the batch_basic_publish library feature. You can batch messages like this:

$msg = new AMQPMessage($msg_body);
$ch->batch_basic_publish($msg, $exchange);

$msg2 = new AMQPMessage($msg_body);
$ch->batch_basic_publish($msg2, $exchange);

and then send the batch like this:

$ch->publish_batch();

When do we publish the message batch?

Let's say our program needs to read from a file and then publish one message per line. Depending on the message size, you will have to decide when it's better to send the batch. You could send it every 50 messages, or every hundred. That's up to you.

Optimized Message Publishing

Another way to speed up your message publishing is by reusing the AMQPMessage message instances. You can create your new message like this:

$properties = array('content_type' => 'text/plain', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT);
$msg = new AMQPMessage($body, $properties);
$ch->basic_publish($msg, $exchange);

Now let's say that while you want to change the message body for future messages, you will keep the same properties, that is, your messages will still be text/plain and the delivery_mode will still be AMQPMessage::DELIVERY_MODE_PERSISTENT. If you create a new AMQPMessage instance for every published message, then those properties would have to be re-encoded in the AMQP binary format. You could avoid all that by just reusing the AMQPMessage and then resetting the message body like this:

$msg->setBody($body2);
$ch->basic_publish($msg, $exchange);

Truncating Large Messages

AMQP imposes no limit on the size of messages; if a very large message is received by a consumer, PHP's memory limit may be reached within the library before the callback passed to basic_consume is called.

To avoid this, you can call the method AMQPChannel::setBodySizeLimit(int $bytes) on your Channel instance. Body sizes exceeding this limit will be truncated, and delivered to your callback with a AMQPMessage::$is_truncated flag set to true. The property AMQPMessage::$body_size will reflect the true body size of a received message, which will be higher than strlen(AMQPMessage::getBody()) if the message has been truncated.

Note that all data above the limit is read from the AMQP Channel and immediately discarded, so there is no way to retrieve it within your callback. If you have another consumer which can handle messages with larger payloads, you can use basic_reject or basic_nack to tell the server (which still has a complete copy) to forward it to a Dead Letter Exchange.

By default, no truncation will occur. To disable truncation on a Channel that has had it enabled, pass 0 (or null) to AMQPChannel::setBodySizeLimit().

Connection recovery

Some RabbitMQ clients using automated connection recovery mechanisms to reconnect and recover channels and consumers in case of network errors.

Since this client is using a single-thread, you can set up connection recovery using exception handling mechanism.

Exceptions which might be thrown in case of connection errors:

PhpAmqpLib\Exception\AMQPConnectionClosedException
PhpAmqpLib\Exception\AMQPIOException
\RuntimeException
\ErrorException

Some other exceptions might be thrown, but connection can still be there. It's always a good idea to clean up an old connection when handling an exception before reconnecting.

For example, if you want to set up a recovering connection:

$connection = null;
$channel = null;
while(true){
    try {
        $connection = new AMQPStreamConnection(HOST, PORT, USER, PASS, VHOST);
        // Your application code goes here.
        do_something_with_connection($connection);
    } catch(AMQPRuntimeException $e) {
        echo $e->getMessage();
        cleanup_connection($connection);
        usleep(WAIT_BEFORE_RECONNECT_uS);
    } catch(\RuntimeException $e) {
        cleanup_connection($connection);
        usleep(WAIT_BEFORE_RECONNECT_uS);
    } catch(\ErrorException $e) {
        cleanup_connection($connection);
        usleep(WAIT_BEFORE_RECONNECT_uS);
    }
}

A full example is in demo/connection_recovery_consume.php.

This code will reconnect and retry the application code every time the exception occurs. Some exceptions can still be thrown and should not be handled as a part of reconnection process, because they might be application errors.

This approach makes sense mostly for consumer applications, producers will require some additional application code to avoid publishing the same message multiple times.

This was a simplest example, in a real-life application you might want to control retr count and maybe gracefully degrade wait time to reconnection.

You can find a more excessive example in #444

UNIX Signals

If you have installed PCNTL extension dispatching of signal will be handled when consumer is not processing message.

$pcntlHandler = function ($signal) {
    switch ($signal) {
        case \SIGTERM:
        case \SIGUSR1:
        case \SIGINT:
            // some stuff before stop consumer e.g. delete lock etc
            pcntl_signal($signal, SIG_DFL); // restore handler
            posix_kill(posix_getpid(), $signal); // kill self with signal, see https://www.cons.org/cracauer/sigint.html
        case \SIGHUP:
            // some stuff to restart consumer
            break;
        default:
            // do nothing
    }
};

pcntl_signal(\SIGTERM, $pcntlHandler);
pcntl_signal(\SIGINT,  $pcntlHandler);
pcntl_signal(\SIGUSR1, $pcntlHandler);
pcntl_signal(\SIGHUP,  $pcntlHandler);

To disable this feature just define constant AMQP_WITHOUT_SIGNALS as true

<?php
define('AMQP_WITHOUT_SIGNALS', true);

... more code

Signal-based Heartbeat

If you have installed PCNTL extension and are using PHP 7.1 or greater, you can register a signal-based heartbeat sender.

<?php

$sender = new PCNTLHeartbeatSender($connection);
$sender->register();
... code
$sender->unregister();

Debugging

If you want to know what's going on at a protocol level then add the following constant to your code:

<?php
define('AMQP_DEBUG', true);

... more code

?>

Benchmarks

To run the publishing/consume benchmark type:

$ make benchmark

Tests

To successfully run the tests you need to first have a stock RabbitMQ broker running locally.Then, run tests like this:

$ make test

Contributing

Please see CONTRIBUTING for details.

Using AMQP 0.8

If you still want to use the old version of the protocol then you can do it by setting the following constant in your configuration code:

define('AMQP_PROTOCOL', '0.8');

The default value is '0.9.1'.

Providing your own autoloader

If for some reason you don't want to use composer, then you need to have an autoloader in place fo the library classes. People have reported to use this autoloader with success.

Original README:

Below is the original README file content. Credits goes to the original authors.

PHP library implementing Advanced Message Queuing Protocol (AMQP).

The library is port of python code of py-amqplib http://barryp.org/software/py-amqplib/

It have been tested with RabbitMQ server.

Project home page: http://code.google.com/p/php-amqplib/

For discussion, please join the group:

http://groups.google.com/group/php-amqplib-devel

For bug reports, please use bug tracking system at the project page.

Patches are very welcome!

Author: Vadim Zaliva [email protected]

Comments
  • Segmentation Fault

    Segmentation Fault

    Our script is dying with a Segmentation Fault in some cases (but not all). It seems to happen in executions of our script which cause a very high number (a few thousand) of messages to be delivered into our queue and it's 100% reproducable with those sets of data. I don't really know how to work with GDB, but I was able to get the following out of it:

    0 zend_std_get_method (object_ptr=0x2959ac0, method_name=0x1f425e0 "connectionClose", method_len=15) at /build/buildd/php5-5.3.10/Zend/zend_object_handlers.c:847

    847 /build/buildd/php5-5.3.10/Zend/zend_object_handlers.c: No such file or directory.

    connectionClose() is called by AbstractConnection's close()method. I tried adding some more sanity checks, such as changing

    if (!$this->protocolWriter || !$this->isConnected()) {
    

    to

    if (!$this->protocolWriter || !$this->isConnected() || !is_object($this->protocolWriter) || !method_exists($this->protocolWriter, 'connectionClose')) {
    

    to no avail. I'm not really sure what GDB is telling me the problem is, so I'm not really sure of the right way to address it. Immediately returning null from the close method has solved our problem in the short-term, but I fear this will end up causing more problems than it solves.

    opened by fixedd 50
  • Error reading data. Recevived 0 instead of expected 1 bytes

    Error reading data. Recevived 0 instead of expected 1 bytes

    Hi, when I try to run

    videlalvaro/php-amqplib/demo/amqp_consumer.php
    

    I've got the error after process completed:

    PHP Fatal error:  Uncaught exception 'PhpAmqpLib\Exception\AMQPRuntimeException' with message 'Error reading data. Received 0 instead of expected 1 bytes' in /application/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php:50
    Stack trace:
    #0 /application/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/AMQPReader.php(106): PhpAmqpLib\Wire\IO\StreamIO->read(1)
    #1 /application/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/AMQPReader.php(145): PhpAmqpLib\Wire\AMQPReader->rawread(1)
    #2 /application/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Connection/AbstractConnection.php(236): PhpAmqpLib\Wire\AMQPReader->read_octet()
    #3 /application/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Connection/AbstractConnection.php(264): PhpAmqpLib\Connection\AbstractConnection->wait_frame(0)
    #4 /application/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Channel/AbstractChannel.php(111): PhpAmqpLib\Connection\AbstractConnection->wait_channel(1, 0)
    #5 /application/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Channel/AbstractChannel.php(207): PhpAmqpLib\Channel\AbstractChannel->next_fram in /application/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php on line 50
    

    What's the problem? Help me please.

    opened by anki-code 49
  • Add support for read timeout

    Add support for read timeout

    the wait method now has a third argument: timeout on read, this setting will be set temporally when used. if timeout is set to 0 (default) then no timeout is applied (BC).

    This feature is useful if you want to add timeout on RPC calls

    opened by rande 47
  • Find a new maintainer for the project

    Find a new maintainer for the project

    As you might know, I'm leaving the company that makes RabbitMQ https://groups.google.com/forum/#!topic/rabbitmq-users/-byffkRnI2w, so I will have even less time to take care of this project. Therefore I'm opening this issue so the community helps with finding a new maintainer(s) for the project.

    While I would like to have a stronger say on who should take care of the project, I would ask contributors and users to propose who you think would be a great candidate. Please comment on this issue and help find that person.

    Besides from knowing PHP, you must be very familiar with at least these concepts: http://www.rabbitmq.com/tutorials/amqp-concepts.html

    opened by videlalvaro 45
  • Support php 8.0

    Support php 8.0

    Overview

    Initially this PR started same as https://github.com/php-amqplib/php-amqplib/pull/854 and https://github.com/php-amqplib/php-amqplib/pull/855 But during testing it I had to make certain changes to make tests run on php 8.0.

    Changes

    • Followed PHP 8.0 standards (no BC)
    • Added php 8.0 to github and travis flows
    • Made tests phpunit9.5-compatible (for php 8.0)
    • Adjusted one method (AbstractIO::select) to work properly under php 8.0 (problem was found by running tests under php 8.0)

    Old description (for history, ignore it)

    https://www.php.net/manual/en/migration80.deprecated.php

    php 8.0 gives a lot of deprecation warnings:

    PHP Deprecated: Required parameter $source follows optional parameter $ticket in /srv/app/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Helper/Protocol/Protocol091.php on line 367
    PHP Deprecated: Required parameter $exchange follows optional parameter $ticket in /srv/app/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Helper/Protocol/Protocol091.php on line 432
    PHP Deprecated: Required parameter $exchange follows optional parameter $ticket in /srv/app/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Helper/Protocol/Protocol091.php on line 516
    PHP Deprecated: Required parameter $exchange follows optional parameter $reply_text in /srv/app/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Helper/Protocol/Protocol091.php on line 644
    PHP Deprecated: Required parameter $routing_key follows optional parameter $reply_text in /srv/app/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Helper/Protocol/Protocol091.php on line 644
    PHP Deprecated: Required parameter $exchange follows optional parameter $redelivered in /srv/app/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Helper/Protocol/Protocol091.php on line 662
    PHP Deprecated: Required parameter $routing_key follows optional parameter $redelivered in /srv/app/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Helper/Protocol/Protocol091.php on line 662
    

    this PR fixes them

    enhancement 
    opened by axxapy 42
  • Notices in PhpAmqpLib/Wire/IO/StreamIO.php during failed fwrite

    Notices in PhpAmqpLib/Wire/IO/StreamIO.php during failed fwrite

    Hey,

    my PHP error log mentioned some notices in a PHP 5.5.1 environment on Ubuntu 12.04:

    [15-Aug-2013 09:13:49 Europe/Berlin] PHP Notice:  fwrite(): send of 12 bytes failed with errno=104 Connection reset by peer in /var/application/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php on line 61
    [15-Aug-2013 09:13:49 Europe/Berlin] PHP Notice:  fwrite(): send of 19 bytes failed with errno=32 Broken pipe in /var/application/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php on line 61
    

    This are only notices and all seems to be working as normal, but i think this has to be fixed. At the moment i do not know any kind of fix for this. Maybe you got an idea.

    watchlist 
    opened by andygrunwald 33
  • Releasing connection reference too early in a channel leads to a segmentation fault

    Releasing connection reference too early in a channel leads to a segmentation fault

    The current channel implementation looks like this:

        public function channel($channel_id = null)
        {
            if (isset($this->channels[$channel_id])) {
                return $this->channels[$channel_id];
            }
    
            $channel_id = $channel_id ? $channel_id : $this->get_free_channel_id();
            $ch = new AMQPChannel($this->connection, $channel_id);
            $this->channels[$channel_id] = $ch;
    
            return $ch;
        }
    

    So as we can see - it does not hold a reference to the connection object but to its connection member.

    This leads to sporadic segfaults.

    And the reason is simple:

    Say you have a code like this:

        private function getClient(array $config)
        {
            $credentials = $config['credentials'];
    
            $conn = new AMQPStreamConnection($credentials['host'], $credentials['port'], $credentials['username'], $credentials['password'], '/');
            $ch = $conn->channel();
            $ch->basic_qos(null, 1, null);
    
            return $ch;
        }
    

    From here - the $conn instance becomes garbage-collectible after you return from the function (it's not referred by any other object).

    So if at any moment php's GC decides to collect it - it invokes its destructor

        public function __destruct()
        {
            if ($this->close_on_destruct) {
                $this->safeClose();
            }
        }
    

    and then when the channel next time tries to read from the socket - it segfaults, since it tries to read from an unmanaged resource.

    Solution: a channel MUST retain a reference to the connection object to prevent it from being garbage collected.

    PS: I commented on https://github.com/php-amqplib/php-amqplib/issues/261 but I believe the problem should be addressed explicitly as a separate issue.

    opened by zerkms 28
  • fwrite(): send of 3728 bytes failed with errno=11 Resource temporarily unavailable

    fwrite(): send of 3728 bytes failed with errno=11 Resource temporarily unavailable

    Since version 2.8.0 I get the exception

    /data/www/web03.adchieve.com/releases/133/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php - 301 - fwrite(): send of 3728 bytes failed with errno=11 Resource temporarily unavailable
    

    I did not have issues in the previous version.

    I use the AMQPStreamConnection and pcntl is installed.

    bug 
    opened by rik-coenders 25
  • bring heartbeat support to socket connection

    bring heartbeat support to socket connection

    As an answer for #272 where AMQPSocketConnection was an issue.

    Actual heartbeat code is taken from StreamIO with adaptation to sockets. Also includes splitting of receive timeout and send timeout as it's done in StreamIO, though there it's $connect_timeout and $read_write_timeout which is hard to be accomplished for sockets

    As soon as this PR is merged I need to update bundle as it passes options incorrectly (or better mimic same constructor everywhere? or better have a builder to fade out all discrepancies between different connection types).

    opened by mente 24
  • PHP Fatal error:  Uncaught ErrorException: fwrite(): send of 19 bytes failed with errno=32

    PHP Fatal error: Uncaught ErrorException: fwrite(): send of 19 bytes failed with errno=32

    Sometimes after send basic_nack

    $message->info['channel']->basic_nack($message->info['delivery_tag']);
    

    Error:

    PHP Fatal error:  Uncaught ErrorException: fwrite(): send of 19 bytes failed with errno=32 Broken pipe in /usr/local/var/www/1vse.loc/yotalot/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php:281
    Stack trace:
    #0 [internal function]: PhpAmqpLib\Wire\IO\StreamIO->error_handler(8, 'fwrite(): send ...', '/usr/local/var/...', 281, Array)
    #1 /usr/local/var/www/1vse.loc/yotalot/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php(281): fwrite(Resource id #99, '\x01\x00\x01\x00\x00\x00\v\x00\x14\x00(\x00\x00\x00\x00...', 8192)
    #2 /usr/local/var/www/1vse.loc/yotalot/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Connection/AbstractConnection.php(327): PhpAmqpLib\Wire\IO\StreamIO->write('\x01\x00\x01\x00\x00\x00\v\x00\x14\x00(\x00\x00\x00\x00...')
    #3 /usr/local/var/www/1vse.loc/yotalot/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Connection/AbstractConnection.php(448): PhpAmqpLib\Connection\AbstractConnection->write('\x01\x00\x01\x00\x00\x00\v\x00\x14\x00(\x00\x00\x00\x00...')
    #4 /usr/local/var/www/1vse.loc/yotalot/vendor in /usr/local/var/www/1vse.loc/yotalot/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php on line 281
    PHP Stack trace:
    PHP   1. yii\base\ErrorHandler->handleException($exception = class ErrorException { protected $message = 'fwrite(): send of 21 bytes failed with errno=32 Broken pipe'; private ${Exception}:string = 'ErrorException: fwrite(): send of 21 bytes failed with errno=32 Broken pipe in /usr/local/var/www/1vse.loc/yotalot/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php:281\nStack trace:\n#0 [internal function]: PhpAmqpLib\\Wire\\IO\\StreamIO->error_handler(8, \'fwrite(): send ...\', \'/usr/local/var/...\', 281, Array)\n#1 /usr/local/var/www/1vse.loc/yotalot/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php(281): fwrite(Resource id #99, \'\\x01\\x00\\x01\\x00\\x00\\x00\\r\\x00<\\x00P\\...'; protected $code = 0; protected $file = '/usr/local/var/www/1vse.loc/yotalot/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php'; protected $line = 281; private ${Exception}:trace = array (0 => array (...), 1 => array (...), 2 => array (...), 3 => array (...), 4 => array (...), 5 => array (...), 6 => array (...), 7 => array (...), 8 => array (...), 9 => array (...), 10 => array (...), 11 => array (...), 12 => array (...), 13 => array (...), 14 => array (...), 15 => array (...), 16 => array (...), 17 => array (...), 18 => array (...), 19 => array (...), 20 => array (...), 21 => array (...), 22 => array (...), 23 => array (...), 24 => array (...), 25 => array (...), 26 => array (...), 27 => array (...)); private ${Exception}:previous = NULL; protected $severity = 8; public $xdebug_message = '\nErrorException: fwrite(): send of 21 bytes failed with errno=32 Broken pipe in /usr/local/var/www/1vse.loc/yotalot/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php on line 281\n\nCall Stack:\n    0.0047     372344   1. {main}() /usr/local/var/www/1vse.loc/yotalot/yii:0\n    0.1164    2978784   2. yii\\base\\Application->run() /usr/local/var/www/1vse.loc/yotalot/yii:31\n    0.1168    3016944   3. yii\\console\\Application->handleRequest(class yii\\console\\Request) /usr/local/var/www/1vse.loc...' }) /usr/local/var/www/1vse.loc/yotalot/vendor/yiisoft/yii2/base/ErrorHandler.php:0
    
    opened by Mirocow 24
  • Is it time for a new release?

    Is it time for a new release?

    It's been almost a year since the previous release.

    Do you mind to collect all these patches and fixes happened during this time under a new shining release?

    opened by therosco 23
  • stream_select(): You MUST recompile PHP with a larger value of FD_SETSIZE

    stream_select(): You MUST recompile PHP with a larger value of FD_SETSIZE

    Version(s) affected: 3.10.7

    Description
    AMQP Runtime exception stream_select(): You MUST recompile PHP with a larger value of FD_SETSIZE. It is set to 1024, but you have descriptors numbered at least as high as 1046. --enable-fd-setsize=2048 is recommended, but you may want to set it to equal the maximum number of open files supported by your system, in order to avoid seeing this error again at a later date

    How to reproduce
    Client PHP using Connection Recovery Cconsume example https://github.com/php-amqplib/php-amqplib/blob/master/demo/connection_recovery_consume.php

    Possible Solution
    first try to understand what the problem is

    Additional context
    Log

    AMQP Runtime exception stream_select(): You MUST recompile PHP with a larger value of FD_SETSIZE. It is set to 1024, but you have descriptors numbered at least as high as 1046. --enable-fd-setsize=2048 is recommended, but you may want to set it to equal the maximum number of open files supported by your system, in order to avoid seeing this error again at a later date.

    opened by ceresaconsultoria 5
  • Fix StreamIO ssl_protocol handling

    Fix StreamIO ssl_protocol handling

    Before this changes AMQPSSLConnection class only connect using ssl when $ssl_options is non empty array.

    This commit fixes that situation.

    While this request is being reviewed, please avoid the widely recommended option:

    ['verify_peer' => false]
    

    Instead use any of PHP SSL context options [0]. I suggest 'verify_peer' with the default value (true):

    ['verify_peer' => true]
    

    Best regards,

    [0] https://www.php.net/manual/en/context.ssl.php

    opened by frikiluser 5
  • Missing documentation for main features

    Missing documentation for main features

    There is a lot of supported AMQP features but documentation is missing. People keep asking how to use this library using github issues but this way is no go.

    Would be nice to have a brief summary about all main features and use cases in some "Read the docs" style documentation.

    Here are things I would like to have documented:

    Exchange types and how to declare them:

    • simple direct
    • fanout demo/amqp_consumer_fanout_1.php
    • topic
    • headers #554 demo/amqp_message_headers_recv.php

    Queue parameters and what they mean.

    #731 #741

    • exclusive queue demo/amqp_consumer_exclusive.php

    Consumer features

    • consumer cancel #704
    • publish confirm demo/amqp_publisher_with_confirms.php
    • handling POSIX signals demo/amqp_consumer_signals.php
    • non blockig consume demo/amqp_consumer_non_blocking.php

    Additional features:

    • delayed messages demo/delayed_message.php
    • dead lettering demo/delayed_message.php
    • exchange to exchange binding demo/e2e_bindings.php

    Connection parameters:

    • how to set connection name #728
    • heartbeats #699 #703 #725
    enhancement 
    opened by ramunasd 3
  • No exception thrown on channel exception from basic.{publish,ack,nack}

    No exception thrown on channel exception from basic.{publish,ack,nack}

    Consider the following example:

    $connection = new AMQPStreamConnection('localhost', 5672, 'user', 'password');
    $channel = $connection->channel();
    
    $channel->basic_publish(new AMQPMessage('message 1'), 'undefined_exchange', 'routing_key'); // here the exception is reported to the channel and channel is closed on RabbitMQ side
    $channel->basic_publish(new AMQPMessage('message 2'), 'defined_exchange', 'routing_key'); // this message, even though valid, will never reach its destination
    

    The defined_exchange already exists and the undefined_exchange does not. First call to basic_publish will result in channel exception being reported to the channel by RabbitMQ and channel being closed. The issue I see here is that in userland we have no clue that this has happened and keep on sending new messages. But they will never arrive to the server because channel has already been closed.

    The same will happen when you have a consumer defined with prefetch grater than 1. Take a look at the following example:

    $connection = new AMQPStreamConnection('localhost', 5672, 'user', 'password');
    $channel = $connection->channel();
    $channel->basic_qos(null, 2, null);
    
    $message = $channel->basic_get('my_queue');
    $channel->basic_ack('invalid_tag'); // here the exception is reported to the channel and channel is closed on RabbitMQ side
    
    $message = $channel->basic_get('my_queue'); // we still get this message because it is already in buffer
    $channel->basic_ack($message->delivery_info['delivery_tag']); // This message will not actually be acknowledged
    

    First message is processed and ack-ed with an invalid delivery_tag. This results in exception being reported to the channel and channel being closed (on the server side). Due to QOS settings there are already other messages in the stream buffer so the library will simply grab the next available message without realizing there was an exception on the channel. The library will eventually figure it out but only after all messages have been already read from the buffer and the next frame that is there, is the exception itself.

    Both of the behaviors can be dangerous. First one because your well defined messages will never reach their destination without any apparent reason. Second one (even though very unlikely) can lead to processing some messages twice when we definitely need to process them only once.

    This behavior also presents itself when people are complaining that there is an exception being raised when they already try to close the connection. This is exactly the same problem. We send close message to the server but instead of getting the response we get previously buffered exception from already closed channel.

    As a solution would be to throw an exception as soon as it is possible to detect there is an exception waiting in a buffer. I do understand that this may impact performance to some extend but it would provide a "logical" behavior.

    Tested on php-amqplib/php-amqplib v2.6.3.

    opened by awons-daft 2
Releases(v3.4.0)
Owner
php-amqplib
PHP Open-Source AMQP Packages
php-amqplib
PHP Library that implements several messaging patterns for RabbitMQ

Thumper Thumper is a PHP library that aims to abstract several messaging patterns that can be implemented over RabbitMQ. Inside the examples folder yo

php-amqplib 276 Nov 20, 2022
RabbitMQ driver for ThinkPHP6 Queue.

RabbitMQ driver for ThinkPHP6 Queue.

null 2 Sep 14, 2022
RabbitMQ driver for Laravel Queue. Supports Laravel Horizon.

RabbitMQ Queue driver for Laravel Support Policy Only the latest version will get new features. Bug fixes will be provided using the following scheme:

Vladimir Yuldashev 1.6k Dec 31, 2022
PHP client for beanstalkd queue

Pheanstalk Next (5) The master branch will be a WIP branch for v5 of this library until it is released. If any patches are needed in v4 they should be

null 1.9k Dec 21, 2022
PHP client for beanstalkd queue

Pheanstalk Pheanstalk is a pure PHP 7.1+ client for the beanstalkd workqueue. It has been actively developed, and used in production by many, since la

null 1.9k Dec 21, 2022
Bernard is a multi-backend PHP library for creating background jobs for later processing.

Bernard makes it super easy and enjoyable to do background processing in PHP. It does this by utilizing queues and long running processes. It supports

Bernard 1.2k Jan 2, 2023
PHP bindings for Tarantool Queue.

Tarantool Queue Tarantool is a NoSQL database running in a Lua application server. It integrates Lua modules, called LuaRocks. This package provides P

Tarantool PHP 62 Sep 28, 2022
Message Queue, Job Queue, Broadcasting, WebSockets packages for PHP, Symfony, Laravel, Magento. DEVELOPMENT REPOSITORY - provided by Forma-Pro

Supporting Enqueue Enqueue is an MIT-licensed open source project with its ongoing development made possible entirely by the support of community and

Enqueue 2.1k Dec 22, 2022
PHP-Queue: A unified front-end for different queuing backends. Includes a REST server, CLI interface and daemon runners.

A unified front-end for different queuing backends. Includes a REST server, CLI interface and daemon runners. Why PHP-Queue? Implementing a

CoderKungfu 646 Dec 30, 2022
The most widely used PHP client for RabbitMQ

php-amqplib This library is a pure PHP implementation of the AMQP 0-9-1 protocol. It's been tested against RabbitMQ. The library was used for the PHP

php-amqplib 4.2k Jan 3, 2023
PHP Kafka client is used in PHP-FPM and Swoole. PHP Kafka client supports 50 APIs, which might be one that supports the most message types ever.

longlang/phpkafka Introduction English | 简体中文 PHP Kafka client is used in PHP-FPM and Swoole. The communication protocol is based on the JSON file in

Swoole Project 235 Dec 31, 2022
A PHP implementation of RabbitMQ Client for webman plugin.

workbunny/webman-rabbitmq ?? A PHP implementation of RabbitMQ Client for webman plugin. ?? A PHP implementation of RabbitMQ Client for webman plugin 常

workbunny 15 Dec 15, 2022
Here is the top 100 PHP functions: it is the list of the most often used PHP native functions

Here is the top 100 PHP functions: it is the list of the most often used PHP native functions. If you are a PHP developer, you must know the Top 100 PHP Functions deeply.

Max Base 16 Dec 11, 2022
Framework used for most of my PHP projects.

PHP boilerplate code that most of my php projects share. Requires php: >=7.3 ext-json: * ext-pdo: * ext-phalcon: >=4.0.0 ext-posix: * ext-

Dennis Stücken 1 Jan 12, 2022
Dockerized PHP development stack: Nginx, MySQL, MongoDB, PHP-FPM, HHVM, Memcached, Redis, Elasticsearch and RabbitMQ

PHP Dockerized Dockerized PHP development stack: Nginx, MySQL, MongoDB, PHP-FPM, HHVM, Memcached, Redis, Elasticsearch and RabbitMQ PHP Dockerized giv

Kasper Isager Dalsgarð 1.1k Dec 30, 2022
Performant pure-PHP AMQP (RabbitMQ) sync/async (ReactPHP) library

BunnyPHP Performant pure-PHP AMQP (RabbitMQ) sync/async (ReactPHP) library Requirements BunnyPHP requires PHP 7.1 and newer. Installation Add as Compo

Jakub Kulhan 641 Dec 29, 2022
PHP Library that implements several messaging patterns for RabbitMQ

Thumper Thumper is a PHP library that aims to abstract several messaging patterns that can be implemented over RabbitMQ. Inside the examples folder yo

php-amqplib 276 Nov 20, 2022
PHP Library that implements several messaging patterns for RabbitMQ

Thumper Thumper is a PHP library that aims to abstract several messaging patterns that can be implemented over RabbitMQ. Inside the examples folder yo

php-amqplib 276 Nov 20, 2022
Поддержка очередей Redis (и на RabbitMq, и на Filesystem, и через DBAL) в Битриксе

Модуль для Битрикса, организующий работу с очередями через Redis (и не только) Поддерживаемый транспорт: Redis RabbitMq Filesystem DBAL Установка comp

Fedy 4 Aug 20, 2021
Curso Laravel Microservices - RabbitMQ

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Ewerton Motta 1 Dec 30, 2021