On Mon, Dec 29, 2025 at 10:24 Larry Garfield <[email protected]> wrote:

> On Sun, Dec 28, 2025, at 3:39 AM, ANDRÁS Zoltán Gyárfás wrote:
> > Hello internals,
> >
> > My name is Zoltán Gyárfás András (aka Zoli). I am a long-time PHP
> > developer, primarily working on large PHP codebases where
> > constructor-based dependency injection is used extensively.
> >
> > Before preparing a formal RFC, I would like to clarify the scope and
> > intent of a small, opt-in idea and gather early feedback from the list.
> >
> > The idea is to introduce a *minimal reflection-based constructor
> > autowiring primitive* into the core, exposed explicitly via the
> > Reflection API, for example:
> >
> > `ReflectionClass::newInstanceAutowire(array $overrides = [], ?callable
> > $resolver = null): object
> > `
> > This proposal is intentionally narrow. To avoid misunderstandings, I
> > would like to clearly explain what the idea *does* and *does not*
> > include.
> >
> > *Key points of the idea, explained in detail:*
> >
> > *1. Explicit opt-in (no change to the `new` operator)*
> > Autowiring would only happen when the developer explicitly calls the
> > new Reflection API.
> > The semantics of the `new` operator remain unchanged. Existing code
> > paths are not affected, and there is no implicit dependency resolution
> > anywhere in the language.
> >
> > *2. No global container or service registry*
> > The proposal does not introduce a global container, service locator, or
> > registry of any kind.
> > Each autowiring operation is local to the call site and bound to the
> > current call stack. No global state is created or reused across calls.
> >
> > *3. No implicit interface-to-implementation mapping*
> > When a constructor depends on an interface or abstract class, the core
> > does not attempt to guess or discover a concrete implementation.
> > Such mappings are inherently policy decisions and vary widely between
> > frameworks. Instead, an explicit resolver callback is required if
> > non-instantiable types are involved.
> >
> > *4. Scalar parameters require overrides or defaults*
> > Scalar and builtin parameters are treated as configuration values. The
> > core does not read environment variables, configuration files, or
> > globals.
> > As a result, scalar parameters must either have default values or be
> > provided explicitly via the `$overrides` argument.
> >
> > *5. Interface and abstract types require an explicit resolver callback*
> > Interfaces and abstract classes are never instantiated automatically.
> > If encountered during autowiring, the core either delegates resolution
> > to the provided resolver callback or fails with a clear exception. This
> > keeps architectural decisions firmly in userland.
> >
> > *6. Deterministic circular dependency detection*
> > Autowiring necessarily builds an object graph. The proposal includes
> > mandatory detection of circular dependencies within that graph.
> > When a cycle is detected, a deterministic and descriptive exception is
> > thrown, rather than allowing infinite recursion or a stack overflow.
> >
> > *7. Request-scope caching of constructor metadata only*
> > For performance reasons, constructor metadata (parameter lists, types,
> > defaults) may be cached for the duration of the request.
> > No object instances are cached, no lifetimes are managed, and no
> > persistent or global caches are introduced.
> >
> > At this stage, I am primarily interested in feedback on whether this
> > level of restraint is sufficient to keep the feature aligned with PHP’s
> > “mechanism, not policy” philosophy, and whether there are any immediate
> > concerns regarding reflection, error handling, or performance.
> >
> > If the direction seems reasonable, I plan to follow up with a draft RFC
> > on wiki.php.net that incorporates the feedback from this discussion.
> >
> > Thank you for your time and insights.
> >
> > Best regards,
> >
> > Zoli
>
> I am unclear what advantage this offers over the status quo, or who the
> intended user is.  Is the intent to be "an alternative to existing DI
> containers" (in which case, what does it offer that would make me use it
> instead of Symfony DI, PHP-DI, rolling my own, etc.), or is it "a tool that
> existing DI containers can use to be better" (in which case, how is it
> better than the existing options for them)?  Those are two different goals
> that would have two different designs.
>
> For example, lazy object proxies already existed in user-space.  However,
> the amount of fugly code it required was high, so moving that logic into
> the engine where it could take advantage of engine-only features to provide
> a far cleaner API and better performance was a win, and allows the removal
> of lots of fugly code from existing projects (when they upgrade).  I'm not
> clear where such a win can be found with this proposal.
>
> --Larry Garfield



I meant to send this question yesterday—it pretty much sums up Larry’s
question, though:

What problem(s) does this solve that can’t or isn’t already solved by a
userland implementation?

I see a lot of detail on the technical aspects of what you’re proposing,
but I don’t see anything about why you’re proposing it.

Cheers,
Ben

Reply via email to