Applications that adopt PHP 8.6's new I/O polling API normally cannot run that code on older PHP versions. Symfony Polyfill 1.41.0 brings this API to PHP 8.1 and later, alongside several compatibility fixes for the Grapheme, Intl and PHP version polyfills.

PHP 8.6 I/O Polling on Older PHP Versions

Nicolas Grekas
Contributed by Nicolas Grekas in #612

Monitoring many sockets, pipes or files with stream_select() requires applications and asynchronous frameworks to manage parallel arrays and account for platform limitations. PHP 8.6 introduces the Io\Poll API, a focused, object-oriented interface for waiting until one or more I/O resources are ready.

The new symfony/polyfill-io-poll package makes the same API available on PHP 8.1 and later:

1
$ composer require symfony/polyfill-io-poll

Create a polling context, register a stream and wait for the requested events:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// src/Network/ConnectionAcceptor.php
namespace App\Network;

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

$server = stream_socket_server('tcp://127.0.0.1:8080');

$poll = new Context();
$poll->add(new StreamPollHandle($server), [Event::Read]);

foreach ($poll->wait(timeoutSeconds: 30) as $watcher) {
    if ($watcher->hasTriggered(Event::Read)) {
        $connection = stream_socket_accept(
            $watcher->getHandle()->getStream(),
        );

        // Process the connection
    }
}

A Context can watch multiple handles for read, write, error and hang-up events. Each call to wait() returns the triggered Watcher objects, which can also carry application data and be modified or removed as requirements change.

The polyfill uses the portable Poll backend and does not support edge-triggered events. On PHP 8.6 and later, the native implementation takes over automatically and can select optimized platform backends such as epoll, kqueue or WSAPoll. The PHP polling API RFC provides the complete API and design details.

Full Changelog

  • #641 [Grapheme] Reject out-of-range offsets in the grapheme_str[ri]?pos() family (@nicolas-grekas)
  • #612 [IoPoll] Polyfill the Io\Poll API (@nicolas-grekas)
  • #637 [Php83][Php85][Grapheme] Throw ValueError on PHP 7 for functions that never returned false (@nicolas-grekas)
  • #638 [Intl][Icu] Avoid pulling deprecated symfony/intl 5.4 on PHP < 8.1 (@nicolas-grekas)
  • #640 [Php74] Align mb_str_split() polyfill with Mbstring and native (@nicolas-grekas)
  • #639 Document the polyfill design principles (@nicolas-grekas)
Published in #Releases