Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129717 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id A06171A00BC for ; Mon, 29 Dec 2025 18:02:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1767031341; bh=xmLOsfH/Uyo+V3oHOyLp9ow74gxf1dliY1KRR52N3TA=; h=References:In-Reply-To:From:Date:Subject:To:From; b=ih9HGmX21MDZnpjPe3QjMJee4n5T+MGa+OykUumHGHmegBNgMsxAP1qnmiYQAduIX iB2Bd3KhLrxURckaBbi1gLNfxICHmBAwS1wK0jReKkGLDd7wdN80EkJaTs37jocaBJ D4qJ41PXZS7kGOZHGj6LSpYq34gTrsS0RztuFz1IM3GWLfTJ1GGwIRh5wKOfdkEesk xFtT1dILY587ynWbOAxIVskZ4M0cff72/GP2r/1tXpb8GRTHhJXVCVS5EgNuMa/7ec yIWr2lhc/CvR5wfNEF9+o3S9k0MaDlkJqZQul3xU0ybAUfOtk4A2+jl6hmOahAM6XD cKsVQ4VX5/PLw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 185DE1801E2 for ; Mon, 29 Dec 2025 18:02:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-yw1-f173.google.com (mail-yw1-f173.google.com [209.85.128.173]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 29 Dec 2025 18:02:19 +0000 (UTC) Received: by mail-yw1-f173.google.com with SMTP id 00721157ae682-78fd6189c88so66024827b3.0 for ; Mon, 29 Dec 2025 10:02:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=benramsey.com; s=google; t=1767031334; x=1767636134; darn=lists.php.net; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=oFtz15QGsFuMjoR5xvdiGBVye7WmH0pEhgh9YWLkniQ=; b=g59hu57Qc43a+cfOp5vuw2fuC5ZIaeSoCgiEpMRsCumoF1shlkJBYwEnmJzf2Mwq5R HdomVcl1/PUAsHG7M9aHUgs82xFovtWNxkHj8M5EZmw+WAIl6e5DRI+6X3DLD4rQuX/z GPP4VhGEQouSBHXSxzE0WoVBtZfLn6VOuQQHVcoMAFG/Fuv0yQ1UdtjjIjkH7FbBCAPJ E3OI4Q4IR4D9xKWMWeZ5pgokWi6BB/Ziht4j1kxotTks1YNFZ3Fu12th1J4Cagzk1jVx jM8tqNRmfXAjsJxpWtoYgnQ8emp92gg6O0P+adR2rIMg/ad11EnypIhvMYbFtcAkZyqe 8Eiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767031334; x=1767636134; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=oFtz15QGsFuMjoR5xvdiGBVye7WmH0pEhgh9YWLkniQ=; b=kL/H2wNgLHmb0AjQXwTBc13mo0NbK4BaRyvDSoMcF0D0t54zzTkq7SM1hveiiiaLdX AB61Pq88wLGcMjkwywGxHsZtaBrxYOFi0bLwV53G01L0oFcHImsZiGR9WqusKttQ5WiY jEVMyh8rYGt7gtfaFsJS+Avh2btCfUKHltvOLhZhfO4VU+gl8xxr6nIWWP6JODC/koeh h1th/kk06eqVfcZnNp+CbaMBxKvcUREL4W/ExnnIRnL8enMRrBV+xgA1BAZwkE9C78Bn /FPJFgC8vsToHPToicCBNRkNURuSj7Yjgjs1GrDfLmI7vjXZinj+BQZCz6KIzu4a/61S 3zkw== X-Gm-Message-State: AOJu0Yyitox7dgf922oWKZqHMKKUFB6F14KRxmdceA4NGeRj8qoXP59H XSvWWZjHGarg24VeC4SfihPY+8eaasHcpWaF40oa4gPU3BwVv4BYGopP8ZWW9gTL72C+4QkI2SK IXVTPn0HT0jbXf87si8bFKO1neAo0SlJYZPsKRdZ+lDscL1VBRZk= X-Gm-Gg: AY/fxX4KwSIB2hlEze5VwSETvERnHeosNp1jsmN5Ua1nYlAy9pOFnKqjP6XgB289RHr 3nrmi42mt7YtywBQpz46zDffNi2s1p+MI+NPL/WOpKVi9OA7KK2R4b99TtB6XhrB1SkN+e9eKSB UTbwotpHAp33Kf6x+PDMpONkBxfrPB9B5rw45wc8boRpZ+KxIsO5eBl1ab54NmlQGMVEFIWzOVx 5bgpruToaoWVuhCy+i4z6MwIlftHEWL69RCENliEFqriPb4MCZjmd0XTO2z97aSs5KOEC6CL+7G Ib07WQ== X-Google-Smtp-Source: AGHT+IGPE8/SIQOn4z+FsqDUV4vM5TbNm9yDzvqxq86NyOq6yzr44t2b1qOv4TBKApcKY/3Fe4TIab185DO4Ns/RhTA= X-Received: by 2002:a05:690c:620b:b0:78f:a7aa:b663 with SMTP id 00721157ae682-78fb3f0d158mr273466157b3.19.1767031333833; Mon, 29 Dec 2025 10:02:13 -0800 (PST) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: <998d891b-d4f9-4fc1-9c71-d7607052506a@app.fastmail.com> In-Reply-To: <998d891b-d4f9-4fc1-9c71-d7607052506a@app.fastmail.com> Date: Mon, 29 Dec 2025 12:02:03 -0600 X-Gm-Features: AQt7F2qspiw1pShIJ9TeCPbOZ9IsgdGm80LFEcf_tI4uj1eFd3-0r0DRxy9-JJk Message-ID: Subject: Re: [PHP-DEV] [Discussion] Reflection-based constructor autowiring (scope clarification) To: PHP Development Content-Type: multipart/alternative; boundary="000000000000f5e08b06471b0ad8" From: ben@benramsey.com (Ben Ramsey) --000000000000f5e08b06471b0ad8 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Mon, Dec 29, 2025 at 10:24 Larry Garfield wrote= : > On Sun, Dec 28, 2025, at 3:39 AM, ANDR=C3=81S Zolt=C3=A1n Gy=C3=A1rf=C3= =A1s wrote: > > Hello internals, > > > > My name is Zolt=C3=A1n Gy=C3=A1rf=C3=A1s Andr=C3=A1s (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 =3D [], ?callabl= e > > $resolver =3D 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= =E2=80=99s > > =E2=80=9Cmechanism, not policy=E2=80=9D philosophy, and whether there a= re 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 th= at > 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 goal= s > 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 provi= de > a far cleaner API and better performance was a win, and allows the remova= l > of lots of fugly code from existing projects (when they upgrade). I'm no= t > clear where such a win can be found with this proposal. > > --Larry Garfield I meant to send this question yesterday=E2=80=94it pretty much sums up Larr= y=E2=80=99s question, though: What problem(s) does this solve that can=E2=80=99t or isn=E2=80=99t already= solved by a userland implementation? I see a lot of detail on the technical aspects of what you=E2=80=99re propo= sing, but I don=E2=80=99t see anything about why you=E2=80=99re proposing it. Cheers, Ben --000000000000f5e08b06471b0ad8 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Mon, Dec 29, 2025 at 10:24 Larry Garfield <larry@garfieldtech.com> wrote:
On Sun, Dec 28, 2025, at 3:39 AM, ANDR=C3=81S Zolt=C3=A1n Gy=C3=A1rf= =C3=A1s wrote:
> Hello internals,
>
> My name is Zolt=C3=A1n Gy=C3=A1rf=C3=A1s Andr=C3=A1s (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 <= br> > 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 =3D [], ?callab= le
> $resolver =3D null): object
> `
> This proposal is intentionally narrow. To avoid misunderstandings, I <= br> > 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 <= br> > 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, o= r
> registry of any kind.
> Each autowiring operation is local to the call site and bound to the <= br> > 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 <= br> > provided explicitly via the `$overrides` argument.
>
> *5. Interface and abstract types require an explicit resolver callback= *
> Interfaces and abstract classes are never instantiated automatically.<= br> > If encountered during autowiring, the core either delegates resolution=
> to the provided resolver callback or fails with a clear exception. Thi= s
> keeps architectural decisions firmly in userland.
>
> *6. Deterministic circular dependency detection*
> Autowiring necessarily builds an object graph. The proposal includes <= br> > 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 <= br> > level of restraint is sufficient to keep the feature aligned with PHP= =E2=80=99s
> =E2=80=9Cmechanism, not policy=E2=80=9D 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 RF= C
> 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 int= ended user is.=C2=A0 Is the intent to be "an alternative to existing D= I containers" (in which case, what does it offer that would make me us= e 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)?=C2=A0 Those are two= different goals that would have two different designs.

For example, lazy object proxies already existed in user-space.=C2=A0 Howev= er, the amount of fugly code it required was high, so moving that logic int= o the engine where it could take advantage of engine-only features to provi= de a far cleaner API and better performance was a win, and allows the remov= al of lots of fugly code from existing projects (when they upgrade).=C2=A0 = I'm not clear where such a win can be found with this proposal.

--Larry Garfield

=
I meant to send this question yesterday=E2=80= =94it pretty much sums up Larry=E2=80=99s question, though:

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

I see a lot of detail o= n the technical aspects of what you=E2=80=99re proposing, but I don=E2=80= =99t see anything about why you=E2=80=99re proposing it.

Cheers,
Ben

= --000000000000f5e08b06471b0ad8--