PHPackages                             makinacorpus/apubsub - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. makinacorpus/apubsub

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

makinacorpus/apubsub
====================

Provides an asynchronous PubSub like API with Drupal implementations

4.0.2(7y ago)513011GPL-2.0-or-laterPHP

Since Nov 28Pushed 7y ago27 watchersCompare

[ Source](https://github.com/makinacorpus/apubsub)[ Packagist](https://packagist.org/packages/makinacorpus/apubsub)[ Docs](http://github.com/makinacorpus/apubsub)[ RSS](/packages/makinacorpus-apubsub/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)DependenciesVersions (12)Used By (1)

Async PubSub
============

[](#async-pubsub)

Provides an asynchronous PubSub like generic API. It allows to send typed messages into communication channels, which will deliver those messages into subscriptions inboxes. Each subscription can mark or unmark its messages as read or unread, fetch them by filtering using basic properties.

It aims to be fast and capable of handling very high message volumetry.

**WARNING: this documentation is outdated, even thought the concepts explained****did not changed, a few details about the implementation did, it will be****as soon as possible, before a stable release**

Getting started
===============

[](#getting-started)

In order to follow this tutorial, you need to have a fully setup and working backend available. Setup and object instanciation will depend upon the choosen backend, so we will consider that the $pubsub object has already been created.

```
// This is our object:
$pubsub = new SomePubSubBackend();

```

Creating a channel
------------------

[](#creating-a-channel)

```
// Simply create the new channel
// The channel instance is returned by the createChannel() method
$channel_foo = $pubsub->createChannel("foo");
$channel_bar = $pubsub->createChannel("bar");
$channel_baz = $pubsub->createChannel("baz");

```

Creating a message
------------------

[](#creating-a-message)

Creating a message is probably the most simple operation of all.

```
// Retrieve our channel
$channel = $pubsub->getChannel("foo");

// And yet it is simple as that
$channel->send("Hello, World!");

```

Using the SubscriberInterface
-----------------------------

[](#using-the-subscriberinterface)

The subscriber is an helper that will keep for you the business mappings between your business identifier and the subscriptions you made for it. This is the most simple way to use this API and will fit most purposes.

The subscriber is a transient object which is not materialized into database. As soon as you make it subscribe to channels, the mapping will be kept, but as soon as you unsubscribe it the mapping will be deleted.

```
// Create a new subscriber
$subscriber = $pubsub->getSubscriber("my_business_id");

// Subscribe to a channel, unlike the subscription, subscribing via the
// subscriber object will directly activate the new subscription
$subscriber->subscribe("foo");
$subscriber->subscribe("bar");
$subscriber->subscribe("baz");

// Fetching subscriber messages
$messages = $subscriber->fetch();

```

Note that messages will be fetched from all active subscriptions and be sorted by creation date

If you need to do more advanced operations on the subscriber subscriptions, you can fetch the subscriptions instances and work directly with it:

```
$subscription = $subscriber->getSubscription("bar");

// For example, deactivate a subscription without deleting it
$subscription->deactivate();

// Or delete another one
$subscriber
    ->getSubscription("baz")
    ->delete();

```

The real use case where you'd need a subscriber instead of working directly with subscriptions is when you need to fetch messages from multiple channels at once (for example, user notifications in a social network).

Working directly with subscription
----------------------------------

[](#working-directly-with-subscription)

Additionally you can bypass the subscriber instance and work only with subscriptions. This method is recommended if you can store the subscription identifiers in your business layer: it will provide best performances since it does not need to keep a mapping on its own.

Subscribing to a channel is basically two things: first create a subscription attached to this channel -a subscription cannot exist without a channel- then activating it.

A subscription instance will always carry an identifier, whose type depends on the backend (but which always will be a PHP primitive scalar type). This identifier is the link you need to store in your business layer in order to be able to later fetch messages or deactivate it: you need to store it by yourself on a higher level.

```
// Retrieve our channel
$channel = $pubsub->getChannel("foo");

// Create the new subscription
$subscription = $channel->subscribe();

// Per default, the subscription is inactive in order to avoid data bloat
// when a subscription is accidentally created
$subscription->activate();

// At this point, you must keep the subscription identifier, else it will
// be lost forever
$subscriptionId = $subscription->getId();

```

Fetching new messages
---------------------

[](#fetching-new-messages)

Fetching new messages will be possible on both a per subscription or subscriber basis.

```
// Retrieve the subscription: the identifier here is the one you kept
// and stored when you created the subscription
$subscription = $pubsub->getSubscription($subscriptionId);

// Fetch operation will only get new messages. The backend may or may not
// let you keep the messages stored depending on both the backend capability
// and configuration
$messages = $subscription->fetch();

```

If you're dealing with user notifications for example, and want to keep them persistent for a while, you'll need to store the messages into your own business API.

History
=======

[](#history)

- master branch is the main development branch for new features
- 0.3 got rid of all objects specific implementations, adds generic cursors for all objects and yet again reduces code. Counter part is a performance regression in update and delete operations, but a performance boots for bulk operations
- 0.2 branch is almost signature compatible with 0.1 branch, and contains numerous internal improvements, and a drastic code quantity reduction. It also cleans up the Drupal modules
- 0.1 branch is the legacy first version, it is kept for compatibility with some prototypes and testing projects that are now in production

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity15

Limited adoption so far

Community20

Small or concentrated contributor base

Maturity70

Established project with proven stability

 Bus Factor1

Top contributor holds 96.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~239 days

Recently: every ~261 days

Total

10

Last Release

2752d ago

Major Versions

0.2.x-dev → 3.0.x-dev2015-12-16

3.0.0 → 4.0.0-rc12015-12-18

2.0.x-dev → 4.0.12018-10-11

### Community

Maintainers

![](https://www.gravatar.com/avatar/69252826f3a70a19fc5dcefb7ef9d26d465bb300245641abb4dd89d0ec391a66?d=identicon)[pounard](/maintainers/pounard)

![](https://www.gravatar.com/avatar/d21b98752b406528da88850922b1061f39bf72eb2126b413d5c12e275811a40b?d=identicon)[Makina Corpus](/maintainers/Makina%20Corpus)

---

Top Contributors

[![pounard](https://avatars.githubusercontent.com/u/341855?v=4)](https://github.com/pounard "pounard (348 commits)")[![SebCorbin](https://avatars.githubusercontent.com/u/645207?v=4)](https://github.com/SebCorbin "SebCorbin (9 commits)")[![Lonnytunes](https://avatars.githubusercontent.com/u/6373159?v=4)](https://github.com/Lonnytunes "Lonnytunes (2 commits)")

### Embed Badge

![Health badge](/badges/makinacorpus-apubsub/health.svg)

```
[![Health](https://phpackages.com/badges/makinacorpus-apubsub/health.svg)](https://phpackages.com/packages/makinacorpus-apubsub)
```

###  Alternatives

[symfony/polyfill-php72

Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions

4.8k674.7M31](/packages/symfony-polyfill-php72)[symfony/polyfill-intl-icu

Symfony polyfill for intl's ICU-related data and classes

2.6k251.4M96](/packages/symfony-polyfill-intl-icu)[nette/php-generator

🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.5 features.

2.2k64.2M574](/packages/nette-php-generator)[consolidation/site-process

A thin wrapper around the Symfony Process Component that allows applications to use the Site Alias library to specify the target for a remote call.

5345.3M8](/packages/consolidation-site-process)[sycho/flarum-profile-cover

Adds the ability to add a cover image to a profile.

1836.6k](/packages/sycho-flarum-profile-cover)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
