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

Reply via email to