Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,25 @@

[Full Changelog](https://github.com/ably/ably-pubsub-php/compare/1.1.12...pubsub-server/2.0.0)

The first release of the `ably/pubsub-server` package. Entries are filled in
before release; see [`UPDATING.md`](./UPDATING.md) for the 1.x migration.
The first release of the `ably/pubsub-server` package, superseding
`ably/ably-php`. See [`UPDATING.md`](./UPDATING.md) for the migration guide and
the full mapping table.

**Breaking changes:**

- The package is now `ably/pubsub-server`, installed with `composer require ably/pubsub-server`. `ably/ably-php` is superseded and receives security and critical-bug fixes only for one year from this release, from the `maintenance/1.x` branch.
- The namespace is now `Ably\PubSub\`. Every class keeps its name, so `Ably\Models\Message` becomes `Ably\PubSub\Models\Message`.
- Clients are constructed through `Ably\PubSub\Server::createHttpClient()`, which declares the server side on the wire. It accepts everything the constructor accepted: an options array, an API key string, a token string, or a `ClientOptions` instance. A client constructed directly declares no side, and is rejected on accounts with monthly-active-user pricing enabled.
- Removed `AblyRest::setAblyAgentHeader()` and `AblyRest::setLibraryFlavourString()`, replaced by the per-client `agents` client option.
- Removed `ably-loader.php`; Composer's autoloader is the only supported install path.
- Removed the `demo/` Heroku application and its `Procfile`.
- The minimum supported PHP version is now 8.1; the SDK is tested on 8.1 through 8.5.

**Other changes:**

- The SDK agent identifier is now `ably-pubsub-php`, and the server side is declared by an `ably-pubsub-server` entry: `Ably-Agent: ably-pubsub-php/2.0.0 php/8.3.4 ably-pubsub-server`.
- Added the `agents` client option (`array<string, string|null>`) so an SDK or framework built on this package can attribute its own traffic.
- `rybakit/msgpack` is now constrained to `^0.9.1 || ^1.0`.

## [1.1.12](https://github.com/ably/ably-php/tree/1.1.12) (2026-06-23)

Expand Down
60 changes: 52 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
![Ably Pub/Sub PHP Header](images/php-SDK-github.png)
[![Latest Stable Version](https://poser.pugx.org/ably/ably-php/v/stable)](https://packagist.org/packages/ably/ably-php)
[![License](https://poser.pugx.org/ably/ably-php/license)](https://github.com/ably/ably-php/blob/main/LICENSE)
[![Latest Stable Version](https://poser.pugx.org/ably/pubsub-server/v/stable)](https://packagist.org/packages/ably/pubsub-server)
[![License](https://poser.pugx.org/ably/pubsub-server/license)](https://github.com/ably/ably-pubsub-php/blob/main/LICENSE)

---

Expand All @@ -26,12 +26,29 @@ Everything you need to get started with Ably:

---

## Package

This SDK ships as a single package, `ably/pubsub-server`.

The package name declares where your code runs. A server is a trusted runtime: it typically authenticates with an API key, one that a browser or a mobile app must never hold, and its connections are exempt from monthly-active-user counting. That declaration has to reach Ably rather than only the README, so the package sends it on every request in the `Ably-Agent` header:

```
Ably-Agent: ably-pubsub-php/2.0.0 php/8.3.4 ably-pubsub-server
```

The trailing `ably-pubsub-server` entry is the part the platform matches on. It is stamped by `Ably\PubSub\Server::createHttpClient()`, so a client constructed any other way declares no side, and will be rejected on accounts that have monthly-active-user pricing enabled.

This is the only Ably Pub/Sub package for PHP. There is no device package and no separate core package to depend on, because PHP is a server-side language: this SDK is REST-only and there is no PHP realtime client. See the [Ably REST API](#ably-rest-api) note below for realtime options.

---

## Supported platforms

Ably aims to support a wide range of platforms. If you experience any compatibility issues, open an issue in the repository or contact [Ably support](https://ably.com/support).

> [!IMPORTANT]
> PHP SDK versions < 1.1.9 will be [deprecated](https://ably.com/docs/platform/deprecate/protocol-v1) from November 1, 2025.
| Platform | Support |
| --- | --- |
| PHP | 8.1, 8.2, 8.3, 8.4, 8.5 |

---

Expand All @@ -42,14 +59,16 @@ For Laravel applications, consider these framework-integrated alternatives that
* **[Ably Pub/Sub PHP Laravel SDK](https://github.com/ably/ably-php-laravel)** - Laravel integration package with clean facade and dependency injection interface.
* **[Ably Broadcaster for Laravel](https://github.com/ably/laravel-broadcaster)** - Official Laravel broadcaster for real-time event broadcasting.

Each needs a new major version to run on `ably/pubsub-server`; their current releases depend on `ably/ably-php` 1.x. Those majors ship in the same release window as this package.

---

## Installation

To get started with your project, install the package:

```sh
composer require ably/ably-php
composer require ably/pubsub-server
```
---

Expand All @@ -59,8 +78,10 @@ composer require ably/ably-php
The following code connects to Ably's REST messaging service, gets reference to a channel to receive messages, and publishes a test message to that same channel:

```php
// Initialize Ably REST client
$ably = new AblyRest(['key' => 'your-ably-api-key', 'clientId' => 'me']);
use Ably\PubSub\Server;

// Initialize the Ably HTTP (REST) client for a server
$ably = Server::createHttpClient(['key' => 'your-ably-api-key', 'clientId' => 'me']);

// Get a reference to the 'test-channel' channel
$channel = $ably->channel('test-channel');
Expand All @@ -69,6 +90,27 @@ $channel = $ably->channel('test-channel');
$channel->publish('test-event', 'hello world');
```

`createHttpClient()` accepts everything the 1.x client constructor accepted: an options array, an API key string, a token string, or a `ClientOptions` instance.

If your own SDK or framework wraps this package, name it so its traffic is attributed to it:

```php
$ably = Server::createHttpClient([
'key' => 'your-ably-api-key',
'agents' => ['my-framework' => '1.2.3'],
]);
```

---

## Migrating from `ably/ably-php` 1.x

`ably/pubsub-server` 2.0.0 supersedes `ably/ably-php`. The client it returns is the same REST client, so for most applications the migration is confined to the `composer require` line, the `use` statements, and the constructor call. [UPDATING.md](./UPDATING.md) has the full mapping table and a before/after example.

If you are staying on 1.x for now, it is maintained on the `maintenance/1.x` branch of this repository, and receives security and critical-bug fixes only for one year from the 2.0.0 release.

---

## Releases

The [CHANGELOG.md](./CHANGELOG.md) contains details of the latest releases for this SDK. You can also view all Ably releases on [changelog.ably.com](https://changelog.ably.com).
Expand All @@ -79,6 +121,8 @@ The [CHANGELOG.md](./CHANGELOG.md) contains details of the latest releases for t

Read the [CONTRIBUTING.md](./CONTRIBUTING.md) guidelines to contribute to Ably.

Development happens in this repository, `ably-pubsub-php`. The Packagist package is published from a read-only distribution mirror, so issues and pull requests belong here.

---

## Support, feedback, and troubleshooting
Expand All @@ -87,4 +131,4 @@ For help or technical support, visit the [Ably Support page](https://ably.com/su

### Ably REST API

This SDK currently supports only the [Ably REST API](https://www.ably.com/docs/rest). For realtime capabilities, you can use the [MQTT adapter](https://www.ably.com/docs/mqtt) alongside [Mosquitto PHP](https://github.com/mgdm/Mosquitto-PHP) to implement Ably's Realtime features.
This SDK currently supports only the [Ably REST API](https://www.ably.com/docs/rest). For realtime capabilities, you can use the [MQTT adapter](https://www.ably.com/docs/mqtt) alongside [Mosquitto PHP](https://github.com/mgdm/Mosquitto-PHP) to implement Ably's Realtime features.
86 changes: 86 additions & 0 deletions UPDATING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Upgrade / Migration Guide

## 1.x (`ably/ably-php`) → 2.0.0 (`ably/pubsub-server`)

> **Status: draft.** The final public API naming is still under review; [PDR-091d](https://ably.atlassian.net/wiki/spaces/product/pages/5363957781) may rename `AblyRest` to `HttpClient` before the 2.0.0 GA release. This section will be finalized before GA.

Version 2.0.0 ships from a new package, `ably/pubsub-server`, under a new namespace, `Ably\PubSub\`. `ably/ably-php` is superseded: it receives security and critical-bug fixes only for one year from the 2.0.0 release date, and is then end-of-life.

Under monthly-active-user pricing the platform has to classify every connection as device-side or server-side. The new package declares that automatically, on every request, in the `Ably-Agent` header; the old constructor cannot declare anything. That is the forcing function for this migration: once monthly-active-user pricing is live, `new Ably\AblyRest(...)` from `ably/ably-php` is rejected on accounts where it is enabled.

The client `Server::createHttpClient()` returns is the same REST client as before. Channels, message publishing, history, presence, authentication, push admin, crypto and every `ClientOptions` key behave exactly as they did in 1.x. For most applications the migration is confined to the `composer require` line, the `use` statements, and the constructor call.

### Mapping

| 1.x (`ably/ably-php`) | 2.0 (`ably/pubsub-server`) |
| --- | --- |
| `composer require ably/ably-php` | `composer require ably/pubsub-server` |
| `use Ably\AblyRest;` / `new AblyRest($opts)` | `use Ably\PubSub\Server;` / `Server::createHttpClient($opts)` |
| `use Ably\Models\Message;` (any `Ably\X` type) | `use Ably\PubSub\Models\Message;` (`Ably\PubSub\X`) |
| `AblyRest::setAblyAgentHeader('x', 'v')` | `Server::createHttpClient(['agents' => ['x' => 'v'], …])` |
| `AblyRest::setLibraryFlavourString('x')` | removed — use the `agents` option |
| `require 'ably-loader.php';` | removed — use Composer's autoloader (`vendor/autoload.php`) |
| PHP 7.2 – 8.0 | PHP `^8.1` (tested on 8.1 – 8.5) |
| ⚠️ [091d](https://ably.atlassian.net/wiki/spaces/product/pages/5363957781): `\Ably\AblyRest` type hints | `\Ably\PubSub\HttpClient` (not yet decided) |

Every class moves namespace and keeps its name, so the rename is mechanical: replace the prefix `Ably\` with `Ably\PubSub\` throughout, including in type hints, `catch` blocks and fully-qualified string class names.

### Example

```php
// 1.x
use Ably\AblyRest;

$ably = new AblyRest(['key' => getenv('ABLY_API_KEY'), 'clientId' => 'me']);
$ably->channel('test-channel')->publish('test-event', 'hello world');

// 2.0
use Ably\PubSub\Server;

$ably = Server::createHttpClient(['key' => getenv('ABLY_API_KEY'), 'clientId' => 'me']);
$ably->channel('test-channel')->publish('test-event', 'hello world');
```

`createHttpClient()` accepts everything the 1.x constructor accepted: an options array, an API key string, a token string, or a `ClientOptions` instance. A `ClientOptions` instance you pass in is copied rather than mutated.

### Declaring the side

Construct through the door. `new Ably\PubSub\AblyRest(...)` still works — the library and its own tests use it — but it declares no side, and will be rejected on monthly-active-user-enabled accounts just as the 1.x constructor is. The door produces:

```
Ably-Agent: ably-pubsub-php/2.0.0 php/8.3.4 ably-pubsub-server
```

If you are building an SDK or framework on top of this package, name it through the `agents` option instead of the removed static setters. Your entries are preserved, in order, ahead of the side entry:

```php
$ably = Server::createHttpClient([
'key' => getenv('ABLY_API_KEY'),
'agents' => ['laravel' => '11.0.0', 'laravel-broadcaster' => '1.0.4'],
]);

// Ably-Agent: ably-pubsub-php/2.0.0 php/8.3.4 laravel/11.0.0 laravel-broadcaster/1.0.4 ably-pubsub-server
```

The `agents` option is per-client, unlike the process-global static setters it replaces, so two clients in one process can carry different attribution.

### Removed in 2.0.0

* `AblyRest::setAblyAgentHeader()` and `AblyRest::$agents` — replaced by the per-client `agents` option.
* `AblyRest::setLibraryFlavourString()` — already deprecated in 1.x; replaced by the same option.
* `ably-loader.php`, the hand-rolled autoloader — Composer is the only supported install path.
* The `demo/` Heroku application and its `Procfile`.
* PHP 7.2 – 8.0 support.

`Auth::authorise()`, the British-spelling alias deprecated in favour of `Auth::authorize()`, is still present in 2.0.0. It may be removed in the 091d pass before GA.

### Unchanged

* The REST client and its whole surface: `channel()`, `channels`, publishing, message history, presence and presence history, `auth`, token requests and token issuing, `push` admin, `stats`, `time()`, and crypto.
* Every `ClientOptions` key, and the array / key-string / token-string / `ClientOptions` forms of the constructor argument.
* Message and error semantics, including `AblyException` and its codes.
* Requirements: `ext-json`, `ext-curl`, `ext-openssl`, and `rybakit/msgpack` for the msgpack protocol.

### Staying on 1.x

`ably/ably-php` 1.x is maintained on the `maintenance/1.x` branch of this repository. It gets security and critical-bug fixes for one year from the 2.0.0 release date and no new features, then reaches end-of-life. Both packages can be installed side by side during a migration: they declare different namespaces and different PSR-4 prefixes, so their autoloading does not collide.
Loading