1. Most PHP frameworks are designed to have all state destroyed at the end of a request. I was trying to integrate a commercial ecommerce framework with something like Road Runner and another one that I forget the name of. The framework had a DI system which provides each module with its own private instance of all injected instances, so having a "worker" that doesn't "boot" everything each request sounded like a good idea (boot was expensive, and a lot of logic was storing module-specific state in module-private instances). I hit a few barriers inside the framework, but actually a lot of them were due to dependencies on PHP global state following state-of-the-art conventions and best practices. It lead to spooky side-effects like cache from one page view loading into the next, and worse. Getting frameworks to run in a loop in PHP can often lead to sharing state in code that was designed in a way that state is assumed to be destroyed soon.
2. PHP depends on lots of unexpected things. If you're deep into language internals already you probably know this however. I was putting symfony2 into a PHP Unikernel a long time ago, and it drove me a bit crazy because everything in the file system, SAPI, locales, etc... it was all missing bridges to something it expected the OS to provide. I ended up making an immutable FS with Nginx and PHP all static linked to each other, but it was really just enough for a POC, a real production ready env would have been a lot more effort. The point is, PHP has a lot of unexpected "hooks" into environments it has grown up around that might be well hidden.
Anyway, really cool project and I like the concept of using a SAPI, I think it has big potential.
I mean, it's not going to be as cheap as getting the thing to actually run in a loop, but it might be enough cheaper than the booting process to be worthwhile.
The big 'gotcha' here is that the heap is typically shared amongst threads in a process and that's where globals tend to live. However, you could make a heap per thread (which is kind of how some implementations of isolates work). You lose a bit of perf by doing this but it does deal with the global stomping problem.
We've (NanoVMs) looked at this a few times. It can be done but as bdg mentioned most frameworks expect state to be in a completely clear so the real challenge is that you have to go in and deal with each framework itself (for instance using WP as an example).
Anyways, I thought FrankenPHP was pretty cool so went ahead and package it up for Nanos: https://repo.ops.city/v2/packages/eyberg/frankenphp/0.0.1/x8... .
If you had a php framework that wasn't so dependent on global state you could definitely make something way more performant.
In general scripting languages and their usage of global state is a recurring concurrency issue but I'm hopeful that the isolate pattern will catch on in other languages to help alleviate it.
https://www.php.net/manual/en/opcache.preloading.php
> preload.php is an arbitrary file that will run once at server startup (PHP-FPM, mod_php, etc.) and load code into persistent memory.
It's interesting to me, because in a big ecomm framework we were getting 80ms PHP page loads, with something like preload it could probably be moved down to 25 or 30ms.