diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d65299..07ab5bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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`) 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) diff --git a/README.md b/README.md index f342813..6b10af9 100644 --- a/README.md +++ b/README.md @@ -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) --- @@ -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 | --- @@ -42,6 +59,8 @@ 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 @@ -49,7 +68,7 @@ For Laravel applications, consider these framework-integrated alternatives that To get started with your project, install the package: ```sh -composer require ably/ably-php +composer require ably/pubsub-server ``` --- @@ -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'); @@ -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). @@ -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 @@ -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. \ No newline at end of file +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. diff --git a/UPDATING.md b/UPDATING.md new file mode 100644 index 0000000..53dbfce --- /dev/null +++ b/UPDATING.md @@ -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.