Hi internals, I would like to ask for early feedback on an idea I have been exploring recently: runtime modules. I put my initial idea in writing here: https://news-web.php.net/php.internals/127343
I have recently been playing around with the idea locally. It seems technically doable, but it touches enough parts of the engine that I would like to check whether this direction makes sense before writing a proper RFC. The problem has been discussed many times over the past few years. I am now looking at it from real-life package level usage with Composer, and how to achieve package symbol isolation in a way that would minimally impact the ecosystem. The rough idea is to have request-lifetime runtime modules. A runtime module would be a named internal unit with its own userland class/function/constant tables. Code running in a module would define symbols into that module, and symbol identity for module-owned code would effectively become `(module, symbol_name)`. The root context would keep the existing behavior, and conceptually we can view it as a root/default module. Root context userland symbols would not automatically be visible to runtime modules. A module would see its own symbols, PHP internal/builtin symbols, and symbols from its direct dependencies. This maps fairly naturally to a Composer style model where a package depends on PHP and on other packages, but not implicitly on application/root symbols. Just to make it clearer, composer related, I see it this way: - each package would be defined in its own module - module dependencies would map directly from Composer package dependencies One possible userland API shape I have been using to experiment with is: ``` module_add_dependency(string $module): void module_run(string $module, Closure $closure): mixed ``` - `module_add_dependency()` declares a module dependency for the current module. - `module_run()` executes the passed closure in the specified module context. - All execution contexts have attached to them the module they were defined for, and any new symbols defined while an execution runs would have the same module. The exception is `module_run()`, which overrides the closure module before running it. The exact API is not the main point at this stage, but I aim to keep it minimal. I am more interested in whether the model itself is reasonable. Technically, the engine would need to track module ownership for compiled code and symbols, keep per-module symbol tables and direct dependency lists, and make lookup, type resolution, autoload, and include_once behavior module aware. Also, due to the dynamic nature of PHP, objects can be passed to module code that might not have their class known, but I do not see this as a blocker. The design I have been considering also rejects visible shadowing: unrelated modules may define the same symbol name, but adding a dependency or declaring a later symbol would fail if it makes two different symbols with the same name visible from the same context. I would like feedback on this package oriented runtime module model, especially whether you see any major technical blockers or design flaws. I aim to work on turning this into a complete RFC within the next 6 months, but it might take more. I am far from experienced with internals details, and I will most probably need guidance and help with the implementation. It is not something I want to rush, as this could be an important addition to the language and we need to get it right. Thank you, Alex
