Hi Larry, Thanks for going through it in this much detail. I've updated the RFC to 0.9.5 with the clarifications you asked for:
- the rule that a scope is bound when a call, fiber or generator is created; - why a scope has no parent link; - a run() example with partial application; - statics and $GLOBALS mentioned in the introduction. The proposal itself is unchanged. https://wiki.php.net/rfc/scope On superglobals starting empty: your legacyLogic() example breaks because it creates a scope. Code that should see the current request doesn't need to: it already runs in the request's scope, and so does every fiber it starts. You create a scope when you start a new unit of work, in practice a new request inside a long-running server. If a new scope inherited its creator's arrays, the server would have to clear them for every request, and one it missed would leak into the next request. A copy would also be shallow: an object stored in $_REQUEST or $_SESSION would be the same instance in both scopes. On request data in statics: that code is already wrong under FrankenPHP's worker mode, RoadRunner and Swoole, whether or not this RFC passes. Scope doesn't make it wrong; it gives that code a key to move the data to. On the WeakMap boilerplate: I see scoped services as the container's job. Most application code never touches Scope. The server creates the scopes, and the container keys its scoped services by them, as ASP.NET Core's container and Spring's scoped proxies do. Your ConnectionProxy is that pattern, written once in the container or the DBAL rather than in every application. I've mentioned an attribute like #[Scoped] under Future Scope, for when containers have settled on a common pattern. On the turtles: they stop at the server. It creates the request's scope and puts the request into it, through $_SERVER under vote A or through the framework's own request holder keyed by the scope. Your ConnectionMaker reads it from there, and everything above it stays a singleton. On a keyword: I'd rather not. Outside containers and servers, Scope::getCurrent() should be rare. Places to point people to: .NET's AddScoped() with IServiceScopeFactory, Spring's @RequestScope with scoped proxies, Python's contextvars and Node's AsyncLocalStorage. Best regards, Frode Børli
