haphpiness

These are things in PHP which make me genuinely_happy();

The Polling API — The I/O Primitive Fibers Were Waiting For

Not out yet. PHP 8.6 is due 19 November 2026, and this one is written and voted through.

Fibers (#6) gave PHP a real concurrency model in 8.1. What they did not come with was a way to ask the operating system "tell me when any of these thousand sockets is ready". Underneath every fiber-based event loop, PHP was still calling stream_select(), and select() has not been the right answer since the 1990s.

// The ceiling nobody wants to hit:
// select() carries an FD_SETSIZE limit, typically 1024 descriptors.
// It is also O(n): every call rescans every descriptor you handed it.
stream_select($read, $write, $except, 0, 1000);

// Meanwhile the kernel has had a better answer for 20 years:
// epoll on Linux, kqueue on BSD and macOS, event ports on Solaris.

8.6 exposes a real polling API, with the platform's best backend chosen for you, and it is available to userland rather than being locked inside the engine.

use Io\Poll\Context;
use Io\Poll\Event;
use Io\Poll\StreamPollHandle;

$ctx = new Context();                      // picks epoll / kqueue / WSAPoll for you

$ctx->add(new StreamPollHandle($socket), Event::Read);

// Edge-triggered and one-shot modes, which select() never offered:
$ctx->add(new StreamPollHandle($other), Event::Read, Event::EdgeTriggered);

foreach ($ctx->wait(timeout: 100) as $watcher) {
    // Event::Read, Write, Error, HangUp, ReadHangUp
}

This is not a feature you will type often. It is the floor the interesting things stand on. ReactPHP, Amp, Swoole, FrankenPHP, and every fiber-based server in the ecosystem have each carried their own polling layer, often in C, often diverging on edge cases. One implementation in core means one set of semantics, and it means a PHP event loop stops falling over at 1024 connections.

Read it next to Fibers and the shape becomes clear. 8.1 delivered the concurrency model. 8.6 delivers the I/O primitive that makes the model scale. That is a five-year arc to finish a single idea, and finishing it is the point.

Significance: Async, Actually

PHP's async story has always had an asterisk: the language had the primitives, but the I/O underneath was a POSIX API with a hard scalability ceiling, so serious event loops shipped their own C extensions. Standardizing the polling layer removes the asterisk. It is infrastructure rather than syntax, and infrastructure is what decides whether an ecosystem's async story is real or aspirational.