I'm not sure why the To/CC list got so long. Please reply to the list, not to 
each person...

On Fri, Nov 21, 2025, at 14:45, Edmond Dantes wrote:
> Hello.
> 
> To use AMPHP you don’t need to run its server. But let’s simplify the 
> situation.
> 
> You have Fiber.
> With Fiber you can build an EventLoop + Scheduler, create two
> coroutines, and then run code inside them that, for example, renders a
> template.
> 
> It will require a fair amount of code, but it’s possible.
> At the same time, ob_start/ob_end will immediately break, because they
> don’t support Fiber switching. This is a known bug.
> And if you pass global state into closures, and that state changes
> unpredictably, the application logic will essentially break.

I don’t know why you’d build all of that from scratch. https://revolt.run/ will 
allow you to run amphp/reactphp in any request. It "just works"

You do need to consciously kick off the event loop, though, as well as install 
some specific extensions, or you’re stuck with the stream_select 
implementation, which isn’t the best.

That being said, the only problem you’d run into trying to install this in a 
WordPress plugin is if *any other plugin* is using Fibers or another Fiber 
library. From experience, they don’t always play nicely together, and there 
should only be one event loop running at a time.

> **What’s different with TrueAsync**
> 
> 1. You don’t need to write a lot of code. Yes, just spawn();
> 2. `ob_start` and `ob_end` will work correctly.
> 3. If closures share a variable that multiple coroutines write to
> unpredictably, the application will still break.

Without well-defined suspension points, literally all code is unpredictable. 
This is what people have been trying to tell you for the last several weeks. 
How can I know when the code will yield to the scheduler? How do I reason about 
it? The foundation is there in the RFC and the code, but it needs more 
definition and guarantees.

> In other words, no matter how asynchrony is implemented in PHP (and
> other langs), it will always require correct handling of shared
> memory.
> And I want to clarify a bit. This is not about a global variable. It’s
> about shared memory. These are not the same things. A local variable
> can be passed into a closure by reference.
> But if you don’t call WP() inside a coroutine, nothing prevents you
> from using asynchrony.

PHP is full of shared memory, even applications. Take, for example:

$val = $this->cache->get('key') ?? $this->cache->set('key', 'value');

Currently in PHP, this is unsafe if the cache is a proper cache (like 
memcached/redis), but for an in-memory implementation, it’s effectively a 
Check-And-Set. If the cache is implemented as async, then it becomes unsafe 
even for in-memory implementations. This may-or-may-not be desired.

However, this gets weird, very quickly, very fast. $_SERVER/$_REQUEST/$_ENV/etc 
are all global memory that usually doesn’t change. However, frameworks change 
it all the time, to inject environment variables from .env files, to sanitise 
inputs, etc. Swoole avoids this by having a Request object. This is simply not 
present in PHP.

Global state is a core part of PHP, like it or not.

— Rob

Reply via email to