{"id":19518778,"url":"https://github.com/ssi-anik/amqp","last_synced_at":"2025-04-05T02:11:55.658Z","repository":{"id":35095407,"uuid":"203738811","full_name":"ssi-anik/amqp","owner":"ssi-anik","description":"php-amqplib wrapper that eases the consumption of RabbitMQ. A painless way of using RabbitMQ","archived":false,"fork":false,"pushed_at":"2023-05-30T10:09:25.000Z","size":165,"stargazers_count":134,"open_issues_count":2,"forks_count":23,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-09-19T03:24:08.748Z","etag":null,"topics":["laravel-rabbitmq","lumen-rabbitmq","php","php-amqp","php-rabbitmq","rabbitmq","rabbitmq-consumer"],"latest_commit_sha":null,"homepage":"https://packagist.org/packages/anik/amqp","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ssi-anik.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-22T07:29:01.000Z","updated_at":"2024-06-23T05:04:52.000Z","dependencies_parsed_at":"2024-06-18T18:14:30.512Z","dependency_job_id":null,"html_url":"https://github.com/ssi-anik/amqp","commit_stats":{"total_commits":175,"total_committers":7,"mean_commits":25.0,"dds":0.07428571428571429,"last_synced_commit":"d63ae01701a6f28551abb6feb49c3842117966a2"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssi-anik%2Famqp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssi-anik%2Famqp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssi-anik%2Famqp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssi-anik%2Famqp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ssi-anik","download_url":"https://codeload.github.com/ssi-anik/amqp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247276189,"owners_count":20912288,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["laravel-rabbitmq","lumen-rabbitmq","php","php-amqp","php-rabbitmq","rabbitmq","rabbitmq-consumer"],"created_at":"2024-11-11T00:14:28.534Z","updated_at":"2025-04-05T02:11:55.641Z","avatar_url":"https://github.com/ssi-anik.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"anik/amqp\n[![codecov](https://codecov.io/gh/ssi-anik/amqp/branch/master/graph/badge.svg?token=M88JATDUHN)](https://codecov.io/gh/ssi-anik/amqp)\n[![PHP Version Require](http://poser.pugx.org/anik/amqp/require/php)](//packagist.org/packages/anik/amqp)\n[![Total Downloads](http://poser.pugx.org/anik/amqp/downloads)](//packagist.org/packages/anik/amqp)\n[![Latest Stable Version](http://poser.pugx.org/anik/amqp/v)](//packagist.org/packages/anik/amqp)\n===\n`anik/amqp` is a php-amqplib wrapper that eases the consumption of RabbitMQ. A painless way of using RabbitMQ.\n\n# Note\n\nPreviously, the package could be used with Laravel, Laravel Zero, Lumen out of the box. From `v2`, the Laravel support\nhas been removed. If you are looking for implementation with Laravel, you can\nuse [anik/laravel-amqp](https://github.com/ssi-anik/laravel-amqp). If you were using this package with Laravel, and you want to upgrade to **Laravel 9**, please consider using [anik/amqp-to-laravel-amqp](https://github.com/ssi-anik/amqp-to-laravel-amqp) if you want to migrate to `anik/laravel-amqp` later.\n\n# Examples\n\nCheckout the [repository](https://github.com/ssi-anik/laravel-rabbitmq-producer-consumer-example) for example.\n\n# Requirements\n\n- PHP `^7.2 | ^8.0`\n- PHP-AMQPLib `^3.0`\n\n# Installation\n\nTo install the package, run\n\u003e `composer require anik/amqp`\n\n# Documentation\n\nFor V1: https://medium.com/@sirajul.anik/rabbitmq-for-php-developers-c17cd019a90\n\n## Connection\n\nTo create an AMQP Connection, you can use\n\n- `Anik\\Amqp\\AmqpConnectionFactory::make`\n- `Anik\\Amqp\\AmqpConnectionFactory::makeFromArray`\n\n```php\n\u003c?php\n\nuse Anik\\Amqp\\AmqpConnectionFactory;\nuse PhpAmqpLib\\Connection\\AMQPLazySSLConnection;\n\n$host = '127.0.0.1';\n$port = 5672;\n$user = 'user';\n$password = 'password';\n$vhost = '/';\n$options = []; // options to be proxied to the amqp connection class\n$ofClass = AMQPLazySSLConnection::class;\n\n$connection = AmqpConnectionFactory::make($host, $port, $user, $password, $vhost, $options, $ofClass);\n$hosts = [\n    [\n        'host' =\u003e $host,\n        'port' =\u003e $port,\n        'user' =\u003e $user,\n        'password' =\u003e $password,\n        'vhost' =\u003e $vhost,\n    ],\n    [\n        'host' =\u003e $host,\n        'port' =\u003e $port,\n        'user' =\u003e $user,\n        'password' =\u003e $password,\n        'vhost' =\u003e $vhost,\n    ]\n];\n\n// With AmqpConnectionFactory::makeFromArray method, you can try to connect to multiple host\n$connection = AmqpConnectionFactory::makeFromArray($hosts, $options, $ofClass);\n```\n\n## Exchange\n\nAlso, there are four specific exchange classes.\n\n- `Anik\\Amqp\\Exchanges\\Direct` for **direct** exchange.\n- `Anik\\Amqp\\Exchanges\\Fanout` for **fanout** exchange.\n- `Anik\\Amqp\\Exchanges\\Headers` for **headers** exchange.\n- `Anik\\Amqp\\Exchanges\\Topic` for **topic** exchange.\n\nYou can still use `Anik\\Amqp\\Exchanges\\Exchange` base class to create your own exchange.\n\nTo instantiate an exchange, you can do like\n\n```php\n\u003c?php\n\nuse Anik\\Amqp\\Exchanges\\Exchange;\nuse Anik\\Amqp\\Exchanges\\Fanout;\nuse Anik\\Amqp\\Exchanges\\Topic;\n\n$exchange = new Exchange('anik.amqp.direct.exchange', Exchange::TYPE_DIRECT);\n\n$exchange = Exchange::make(['name' =\u003e 'anik.amqp.direct.exchange', 'type' =\u003e Exchange::TYPE_DIRECT]);\n\n$exchange = new Topic('anik.amqp.topic.exchange');\n\n$exchange = Fanout::make(['name' =\u003e 'anik.amqp.fanout.exchange']);\n```\n\nWhen creating an exchange instance with\n\n- `Exchange::make` - `name` and `type` keys must be present in the given array.\n- `Topic::make` `Fanout::make` `Headers::make` `Direct::make` - `name` key must be present in the given array.\n\n`Anik\\Amqp\\Exchanges\\Exchange` contains a few predefined exchange types, you can use them as reference.\n\n- `TYPE_DIRECT` for **direct** type.\n- `TYPE_TOPIC` for **topic** type.\n- `TYPE_FANOUT` for **fanout** type.\n- `TYPE_HEADERS` for **headers** type.\n\nThe `Exchange::make` method also accepts the following keys when making an exchange instance.\n\n- `declare` Type: `bool`. Default: `false`. If you want to declare the exchange.\n- `passive` Type: `bool`. Default: `false`. If the exchange is passive.\n- `durable` Type: `bool`. Default: `true`. If the exchange is durable.\n- `auto_delete` Type: `bool`. Default: `false`. If the exchange should auto delete.\n- `internal` Type: `bool`. Default: `false`. If the exchange is internal.\n- `no_wait` Type: `bool`. Default: `false`. If the client should not wait for the server's reply.\n- `arguments` Type: `array`. Default: `[]`.\n- `ticket` Type: `null | integer`. Default: `null`.\n\nYou can also reconfigure the exchange instance using `$exchange-\u003ereconfigure($options)`. The `$options` array accepts\nthe above keys as well.\n\nAlso, you can use the following methods to configure your exchange instance.\n\n- `setName` - Accepts: `string`. The only way to change exchange name after instantiation.\n- `setDeclare` - Accepts: `bool`.\n- `setType` - Accepts: `bool`.\n- `setPassive` - Accepts: `bool`.\n- `setDurable` - Accepts: `bool`.\n- `setAutoDelete` - Accepts: `bool`.\n- `setInternal` - Accepts: `bool`.\n- `setNowait` - Accepts: `bool`.\n- `setArguments` - Accepts: `array`.\n- `setTicket` - Accepts: `null | integer`.\n\n## Queue\n\nTo instantiate a queue, you can do like\n\n```php\n\u003c?php\n\nuse Anik\\Amqp\\Queues\\Queue;\n\n$queue = new Queue('anik.amqp.direct.exchange.queue');\n\n$queue = Queue::make(['name' =\u003e 'anik.amqp.direct.exchange.queue']);\n```\n\nWhen creating a queue instance with\n\n- `Queue::make` - `name` keys must be present in the given array.\n\nThe `Queue::make` method also accepts the following keys when making a queue instance.\n\n- `declare` Type: `bool`. Default: `false`. If you want to declare the queue.\n- `passive` Type: `bool`. Default: `false`. If the queue is passive.\n- `durable` Type: `bool`. Default: `true`. If the queue is durable.\n- `exclusive` Type: `bool`. Default: `false`. If the queue is exclusive.\n- `auto_delete` Type: `bool`. Default: `false`. If the queue should auto delete.\n- `no_wait` Type: `bool`. Default: `false`. If the client should not wait for the server's reply.\n- `arguments` Type: `array`. Default: `[]`.\n- `ticket` Type: `null | integer`. Default: `null`.\n\nYou can also reconfigure the queue instance using `$queue-\u003ereconfigure($options)`. The `$options` array accepts the\nabove keys as well.\n\nAlso, you can use the following methods to configure your queue instance.\n\n- `setName` - Accepts: `string`. The only way to change queue name after instantiation.\n- `setDeclare` - Accepts: `bool`.\n- `setType` - Accepts: `bool`.\n- `setPassive` - Accepts: `bool`.\n- `setDurable` - Accepts: `bool`.\n- `setExclusive` - Accepts: `bool`.\n- `setAutoDelete` - Accepts: `bool`.\n- `setNowait` - Accepts: `bool`.\n- `setArguments` - Accepts: `array`.\n- `setTicket` - Accepts: `null | integer`.\n\n## Qos\n\nTo instantiate a Qos, you can do like\n\n```php\n\u003c?php\n\nuse Anik\\Amqp\\Qos\\Qos;\n\n$prefetchSize = 0;\n$prefetchCount = 0;\n$global = false;\n\n$qos = new Qos($prefetchSize, $prefetchCount, $global);\n\n$qos = Queue::make(['prefetch_size' =\u003e $prefetchSize, 'prefetch_count' =\u003e $prefetchCount, 'global' =\u003e $global]);\n```\n\nThe `Qos::make` method also accepts the following key when making a qos instance.\n\n- `prefetch_size` Type: `int`. Default: `0`.\n- `prefetch_count` Type: `int`. Default: `0`.\n- `global` Type: `bool`. Default: `true`.\n\nYou can also reconfigure the qos instance using `$qos-\u003ereconfigure($options)`. The `$options` array accepts the above\nkeys as well.\n\nAlso, you can use the following methods to configure your qos instance.\n\n- `setPrefetchCount` - Accepts: `int`.\n- `setPrefetchSize` - Accepts: `int`.\n- `setGlobal` - Accepts: `bool`.\n\n## Publish/Produce message\n\nTo produce/publish messages, you'll need the `Anik\\Amqp\\Producer` instance. To instantiate the class\n\n```php\n\u003c?php\n\nuse Anik\\Amqp\\Producer;\n\n$producer = new Producer($connection, $channel);\n```\n\nThe constructor accepts\n\n- `$connection` Type: `PhpAmqpLib\\Connection\\AbstractConnection`. Required.\n- `$channel` Type: `null | PhpAmqpLib\\Channel\\AMQPChannel`. Optional.\n\nIf `$channel` is not provided or **null**, class uses the channel from the `$connection`.\n\nOnce the producer class is instantiated, you can set a channel with `setChannel`. Method\naccepts `PhpAmqpLib\\Channel\\AMQPChannel` instance.\n\nThere are three ways to publish messages\n\n### Bulk Publish\n\n`Producer::publishBatch` - to publish multiple messages in bulk.\n\n```php\n\u003c?php\n\nuse Anik\\Amqp\\Producer;\n\n(new Producer($connection))-\u003epublishBatch($messages, $routingKey, $exchange, $options);\n``` \n\n- `$messages` Type: `Anik\\Amqp\\Producible[]`. If any of the message is not the type of `Producible` interface, it'll\n  throw error.\n- `$routingKey` Type: `string`. Routing key. Default `''` (empty string).\n- `$exchange` Type: `null | Anik\\Amqp\\Exchanges\\Exchange`.\n- `$options` Type: `array`. Runtime configuration.\n    * Key `exchange` - Accepts: `array`.\n        - If you pass `null` as `$exchange`, then you must provide a valid configuration through this key to create an\n          exchange under the hood. If you pass `$exchange` with Exchange instance and `$options['exchange']`, exchange\n          instance will be reconfigured accordingly with the values available in `$options['exchange']`. Keys are same\n          as `Exchange::make`'s `$options`.\n    * Key `publish` - Accepts: `array`.\n        - Key `mandatory` Default `false`.\n        - Key `immediate` Default `false`.\n        - Key `ticket` Default `null`.\n        - Key `batch_count`. Default: `500`. To make a batch of **X** messages before publishing a batch.\n\n### Publish\n\n`Producer::publish` - to publish a single message. Uses `Producer::publishBatch` under the hood.\n\n```php\n\u003c?php\n\nuse Anik\\Amqp\\Producer;\n\n(new Producer($connection))-\u003epublish($message, $routingKey, $exchange, $options);\n``` \n\n- `$message` Type: `Anik\\Amqp\\Producible`.\n- `$routingKey` Type: `string`. Routing key. Default `''` (empty string).\n- `$exchange` Type: `null | Anik\\Amqp\\Exchanges\\Exchange`.\n- `$options` Type: `array`. Runtime configuration.\n    * Key `exchange` - Accepts: `array`.\n        - If you pass `null` as `$exchange`, then you must provide a valid configuration through this key to create an\n          exchange under the hood. If you pass `$exchange` with Exchange instance and `$options['exchange']`, exchange\n          instance will be reconfigured accordingly with the values available in `$options['exchange']`. Keys are same\n          as `Exchange::make`'s `$options`.\n    * Key `publish` - Accepts: `array`.\n        - Key `mandatory` Default `false`.\n        - Key `immediate` Default `false`.\n        - Key `ticket` Default `null`.\n\n### Publish Basic\n\n`Producer::publishBasic` - to publish a single message using `AMQPChannel::basic_publish` method.\n\n```php\n\u003c?php\n\nuse Anik\\Amqp\\Producer;\n\n(new Producer($connection))-\u003epublishBasic($message, $routingKey, $exchange, $options);\n``` \n\n- `$message` Type: `Anik\\Amqp\\Producible`.\n- `$routingKey` Type: `string`. Routing key. Default `''` (empty string).\n- `$exchange` Type: `null | Anik\\Amqp\\Exchanges\\Exchange`.\n- `$options` Type: `array`. Runtime configuration.\n    * Key `exchange` - Accepts: `array`.\n        - If you pass `null` as `$exchange`, then you must provide a valid configuration through this key to create an\n          exchange under the hood. If you pass `$exchange` with Exchange instance and `$options['exchange']`, exchange\n          instance will be reconfigured accordingly with the values available in `$options['exchange']`. Keys are same\n          as `Exchange::make`'s `$options`.\n    * Key `publish` - Accepts: `array`.\n        - Key `mandatory` Default `false`.\n        - Key `immediate` Default `false`.\n        - Key `ticket` Default `null`.\n\n## ProducibleMessage: Implementation of Producible Interface\n\nThe package comes with `Anik\\Amqp\\ProducibleMessage`, a generic implementation of `Anik\\Amqp\\Producible` interface.\n\nYou can instantiate the class like\n\n```php\n\u003c?php\n\nuse Anik\\Amqp\\ProducibleMessage;\nuse PhpAmqpLib\\Message\\AMQPMessage;\nuse PhpAmqpLib\\Wire\\AMQPTable;\n\n$msg = new ProducibleMessage('take my message to rabbitmq');\n\n$msg = new ProducibleMessage('take my message to rabbitmq', [\n    'delivery_mode' =\u003e AMQPMessage::DELIVERY_MODE_PERSISTENT,\n]);\n\n$msg = (new ProducibleMessage())-\u003esetMessage('take my message to rabbitmq')-\u003esetProperties([\n    'delivery_mode' =\u003e AMQPMessage::DELIVERY_MODE_PERSISTENT,\n    'application_headers' =\u003e new AMQPTable(['key' =\u003e 'value']),\n]);\n```\n\n## Consumer\n\nTo consume messages, you'll need the `Anik\\Amqp\\Consumer` instance. To instantiate the class\n\n```php\n\u003c?php\n\nuse Anik\\Amqp\\Consumer;\n\n$consumer = new Consumer($connection, $channel, $options);\n```\n\nThe constructor accepts\n\n- `$connection` Type: `PhpAmqpLib\\Connection\\AbstractConnection`. Required.\n- `$channel` Type: `null | PhpAmqpLib\\Channel\\AMQPChannel`. Optional.\n- `$options` Type: `array`. Optional. Configurations for consumer.\n    * `tag` Type: `string`. Default `sprintf(\"anik.amqp_consumer_%s_%s\", gethostname(), getmypid())`. To set consumer\n      tag.\n    * `no_local` Type: `bool`. Default `false`.\n    * `no_ack` Type: `bool`. Default `false`.\n    * `exclusive` Type: `bool`. Default `false`.\n    * `no_wait` Type: `bool`. Default `false`.\n    * `arguments` Type: `bool`. Default `[]`.\n    * `ticket` Type: `null | int`. Default `null`.\n\nIf `$channel` is not provided or **null**, class uses the channel from the `$connection`.\n\nOnce the consumer class is instantiated, you can access the following methods.\n\n- `setChannel` - Accepts: `PhpAmqpLib\\Channel\\AMQPChannel` instance.\n- `reconfigure` - Accepts: `array`. To reconfigure the instance. Valid keys are same as constructor's options keys.\n- `setConsumerTag` - Accepts: `string`. Default `sprintf(\"anik.amqp_consumer_%s_%s\", gethostname(), getmypid())`.\n- `setNoLocal` - Accepts: `bool`. Default `false`.\n- `setNoAck` - Accepts: `bool`. Default `false`.\n- `setExclusive` - Accepts: `bool`. Default `false`.\n- `setNowait` - Accepts: `bool`. Default `false`.\n- `setArguments` - Accepts: `array`. Default `[]`.\n- `setTicket` - Accepts: `null | int`. Default `null`.\n\nTo consume messages,\n\n```php\n\u003c?php\n\nuse Anik\\Amqp\\Consumer;\n\n(new Consumer($connection, $channel, $options))-\u003econsume($handler, $bindingKey, $exchange, $queue, $qos, $options);\n```\n\n- `$handler` Type: `Anik\\Amqp\\Consumable`.\n- `$bindingKey` Type: `string`. Binding key. Default `''` (empty string).\n- `$exchange` Type: `null | Anik\\Amqp\\Exchanges\\Exchange`.\n- `$queue` Type: `null | Anik\\Amqp\\Queues\\Queue`.\n- `$qos` Type: `null | Anik\\Amqp\\Qos\\Qos`.\n- `$options` Type: `array`. Runtime configuration.\n    * `consumer` - Accepts: `array`. Keys are same as `Consumer::__construct`'s options.\n    * `exchange` - Accepts: `array`. Keys are same as `Exchange::make`'s options.\n        - If you pass `null` as `$exchange`, then you must provide a valid configuration through this key to create an\n          exchange under the hood. If you pass `$exchange` with Exchange instance and `$options['exchange']`, exchange\n          instance will be reconfigured accordingly with the values available in `$options['exchange']`.\n    * `queue` - Accepts: `array`. Keys are same as `Queue::make`'s options.\n        - If you pass `null` as `$queue`, then you must provide a valid configuration through this key to create a queue\n          under the hood. If you pass `$queue` with Queue instance and `$options['queue']`, queue instance will be\n          reconfigured accordingly with the values available in `$options['queue']`.\n    * `qos` - Accepts: `array`. Keys are same as `Qos::make`'s options.\n        - If you pass `$qos` with Qos instance and `$options['qos']`, qos instance will be reconfigured accordingly.\n          If `$qos` is null and `$options['qos']` holds value, QoS will be applied to the channel. If `$qos` is `null`\n          and `$options['qos']` is not available, **NO QoS WILL BE APPLIED TO THE CHANNEL**\n    * `bind` - Accepts: `array`. For binding queue to the exchange.\n        - `no_wait`. Default `false`.\n        - `arguments`. Default `[]`.\n        - `ticket`. Default `null`.\n    * `consume` - Accepts: `array`. Following values are passed to the `AMQPChannel::wait()`.\n        - `allowed_methods` Default `null`.\n        - `non_blocking` Default `false`.\n        - `timeout` Default `0`.\n\n## ConsumableMessage: Implementation of Consumable Interface\n\nThe package comes with `Anik\\Amqp\\ConsumableMessage`, a generic implementation of `Anik\\Amqp\\Consumable` interface.\n\nYou can instantiate the class like\n\n```php\n\u003c?php\n\nuse Anik\\Amqp\\ConsumableMessage;\n// use PhpAmqpLib\\Message\\AMQPMessage;\n\n$msg = new ConsumableMessage(function (ConsumableMessage $message/*, AMQPMessage $original*/) {\n    echo $message-\u003egetMessageBody() . PHP_EOL;\n    echo $message-\u003egetRoutingKey() . PHP_EOL;\n    $message-\u003eack();\n    // Alternatively, $original-\u003eack();\n\n    /** \n     * Method: `decodeMessage` \n     * Returns:\n     *      - `array` if message body contains valid json\n     *      - `null` if json could not be decoded \n     */\n    var_dump($message-\u003edecodeMessage());\n\n    /** \n     * Method: `decodeMessageAsObject` \n     * Returns:\n     *      - `\\stdClass` if message body contains valid json\n     *      - `null` if json could not be decoded \n     */\n    var_dump($message-\u003edecodeMessageAsObject());\n});\n```\n\n**NOTE**: Calling any method on `ConsumableMessage` instance without setting **AMQPMessage** will throw exception.\n\n# Issues?\n\nIf you find any issue/bug/missing feature, please submit an issue and PRs if possible. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fssi-anik%2Famqp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fssi-anik%2Famqp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fssi-anik%2Famqp/lists"}