Every blocking call in PHP stops the whole process. fread() waits for data, sleep() waits for the clock, and curl_exec() waits for the server. Fibers, added in PHP 8.1, let you pause and resume code. But they can't help here, because these functions never pause. They just block.

Jakub Zelenka's RFC adds a hook so an event loop or Fiber scheduler can take over those waits. The RFC calls this a provider. When a Fiber calls fread() and no data is ready, PHP hands the wait to the provider. The provider pauses that Fiber and runs another one. When the data arrives, the first Fiber picks up where it left off. Your code still just calls fread().

What changes

Libraries like AMPHP, ReactPHP and Revolt handle this today by rewriting sockets, HTTP clients and DNS in PHP. Anything that uses the standard library, like a database driver or an SDK built on curl, still blocks. With a provider installed, that existing code can run side by side without changes.

Here is the RFC's example. Scheduler is a small userland provider the RFC shows in full, about fifty lines:

$provider = new Scheduler(new \Io\Poll\OperationQueue());
\Io\Hooks\set_hooks($provider);

$provider->spawn(function () {
    $c = stream_socket_client('tcp://example.org:80');
    fwrite($c, "GET / HTTP/1.0\r\nHost: example.org\r\n\r\n");
    echo strlen(stream_get_contents($c)), " bytes\n";
});
$provider->spawn(function () {
    sleep(1); // the other Fibers run meanwhile
    $ch = curl_init('https://example.org/');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    echo strlen(curl_exec($ch)), " bytes\n";
});

$provider->loop();

The hooks cover streams, sockets, curl, OpenSSL, the sleep functions, name lookups and process waits. Some things still block, including exec(), flock() without LOCK_NB, and extensions like pgsql that manage their own connections. File reads and name lookups can only run without blocking through a follow-up RFC, the Ring API.

PHP doesn't get a built-in scheduler. The RFC only adds the hook. The provider decides what runs while something waits, and you can write one in PHP.

What it means for existing code

Without a provider, one thing changes. Socket descriptors become non-blocking while a stream holds them. Code that pulls a descriptor out of a stream, for example with socket_import_stream(), will see that.

With a provider installed, blocking calls become points where other Fibers can run. Code that relies on global state, like a WordPress plugin, could see that state change during a database query. Using one stream or curl handle from two Fibers at once now throws an Error. Nothing changes unless an app installs a provider.

Where it stands

Jakub Zelenka announced the RFC on the internals list on September 30, 2026, and calls it early stage. It targets PHP 8.7 and depends on the Polling API Additions RFC. A proof of concept is in php-src PR #23997. A vote would need a two-thirds majority.