[PHP-DEV] [RFC] Polling API

Hi,

On Thu, Oct 30, 2025 at 10:06 PM Jakub Zelenka <bukka@php.net> wrote:

Hello,

I would like to introduce a new polling API RFC that is part of my stream evolution work:

https://wiki.php.net/rfc/poll_api

Just a heads up that I plan to open voting on Tuesday 31st March around the same time like now.

Kind regards,

Jakub

Hi

Sorry for the late feedback, it's hard juggling all the different RFCs that are in progress to provide meaningful feedback.

Am 2026-03-11 22:07, schrieb Jakub Zelenka:

> I also think that there is not really much use case for user space to
> implement their own handles so such interface would be used only
> internally
> anyway.

This applies equally to interfaces and abstract methods. The abstract
base class however will make it much weirder when a specific (future)
handle might need to implement additional interfaces or abstract
classes.

> In addition interface would effectively expose the internal stream fd
> which
> is currently hidden and makes harder messing up with stream fd which
> might
> cause various issues.

I don't understand that point. For both an interface and an abstract
method, the method would exist on the child class and thus can be called
by a developer.

Well if it is abstract, then the method can be protected and because the
classes are final, user spaces cannot call it. But for interface I would

Protected methods of internal classes should still be accessible to Reflection.

need to make it public which means that StreamHandle would need to expose
callabable (public) method. I know that I could just return 0 and use
different handling internally but I think this would be surprising and
created obvious inconsistency. I mean it's fine if the calls happen
internally but if the exposed methods are just dummy and return nonsense
for user space, then I don't think it would be a good design.

It's equally weird that there is a protected method that is effectively internally called by an unrelated class (Context) that is not supposed to know about it. Perhaps the correct solution would then be removing the `getFileDescriptor()` method from the public API entirely and change `Handle` to be an empty “marker interface” that cannot be implemented in userland (similarly to Throwable) to leave all options open for the future?

Best regards
Tim Düsterhus

вс, 29 мар. 2026 г., 23:54 Jakub Zelenka <bukka@php.net>:

Hi,

On Thu, Oct 30, 2025 at 10:06 PM Jakub Zelenka <bukka@php.net> wrote:

Hello,

I would like to introduce a new polling API RFC that is part of my stream evolution work:

https://wiki.php.net/rfc/poll_api

Just a heads up that I plan to open voting on Tuesday 31st March around the same time like now.

Kind regards,

Jakub

Hi, Jakub!

Why do you use get and is methods if we have powerful prioritize with get hooks nowadays? I think that PHP should promote its modern features in its own API.

Hi,

On Tue, Mar 31, 2026 at 11:41 AM Valentin Udaltsov <udaltsov.valentin@gmail.com> wrote:

вс, 29 мар. 2026 г., 23:54 Jakub Zelenka <bukka@php.net>:

Hi,

On Thu, Oct 30, 2025 at 10:06 PM Jakub Zelenka <bukka@php.net> wrote:

Hello,

I would like to introduce a new polling API RFC that is part of my stream evolution work:

https://wiki.php.net/rfc/poll_api

Just a heads up that I plan to open voting on Tuesday 31st March around the same time like now.

Kind regards,

Jakub

Hi, Jakub!

Why do you use get and is methods if we have powerful prioritize with get hooks nowadays? I think that PHP should promote its modern features in its own API.

There is actually no internal API for hooks so it would require using object handlers (which is from the user space point of view just __get). It means no stubs declaration either. We also don’t have an internal policy where to use hooks and where methods. So there are still lots of blockers to start using it in core.

Kind regards,

Jakub

Hi,

On Tue, Mar 31, 2026 at 11:23 AM Tim Düsterhus <tim@bastelstu.be> wrote:

Hi

Sorry for the late feedback, it’s hard juggling all the different RFCs
that are in progress to provide meaningful feedback.

Am 2026-03-11 22:07, schrieb Jakub Zelenka:

I also think that there is not really much use case for user space to
implement their own handles so such interface would be used only
internally
anyway.

This applies equally to interfaces and abstract methods. The abstract
base class however will make it much weirder when a specific (future)
handle might need to implement additional interfaces or abstract
classes.

In addition interface would effectively expose the internal stream fd
which
is currently hidden and makes harder messing up with stream fd which
might
cause various issues.

I don’t understand that point. For both an interface and an abstract
method, the method would exist on the child class and thus can be
called
by a developer.

Well if it is abstract, then the method can be protected and because
the
classes are final, user spaces cannot call it. But for interface I
would

Protected methods of internal classes should still be accessible to
Reflection.

Good point.

need to make it public which means that StreamHandle would need to
expose
callabable (public) method. I know that I could just return 0 and use
different handling internally but I think this would be surprising and
created obvious inconsistency. I mean it’s fine if the calls happen
internally but if the exposed methods are just dummy and return
nonsense
for user space, then I don’t think it would be a good design.

It’s equally weird that there is a protected method that is effectively
internally called by an unrelated class (Context) that is not supposed
to know about it. Perhaps the correct solution would then be removing
the getFileDescriptor() method from the public API entirely and change
Handle to be an empty “marker interface” that cannot be implemented in
userland (similarly to Throwable) to leave all options open for the
future?

This (marker interface just for internal classes) is actually a really good idea. Will change it.

Thanks

Jakub

Hi

Am 2026-03-31 15:23, schrieb Jakub Zelenka:

There is actually no internal API for hooks so it would require using
object handlers (which is from the user space point of view just __get). It
means no stubs declaration either. We also don't have an internal policy
where to use hooks and where methods. So there are still lots of blockers
to start using it in core.

While I agree with the conclusion that using hooks internally is complicated and there is no real policy there, Valentin was actually making a good point: We could use regular `readonly` properties for those cases where we're just exposing a “constructor parameter”. Specifically:

- Context::getBackend() -> public readonly Backend $backend;
- Watcher::getHandle() -> public readonly Handle $handle;

Potentially Watcher::$data could also be a regular (non-readonly) property, or does `modifyData()` contain additional logic that is not just “store the value somewhere”?

There is precedent for this kind of regular `readonly` property referring to an input object in ext/random with Randomizer::$engine: php-src/ext/random/random.stub.php at 32c1931f18109655bc074dd5cda3248b838de636 · php/php-src · GitHub

Best regards
Tim Düsterhus