Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129157 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 528E51A00BC for ; Sat, 8 Nov 2025 21:57:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1762639045; bh=ETD6w1RMpcpEir5LVdlOMh2Cylomidvx0QghP2dF8pc=; h=Date:From:To:In-Reply-To:References:Subject:From; b=MwnyWjFudKJJBFDoHKTk90g9foS8n98w6I3CyGF3OadT8j8zJ9VJu/3EaGJumwdq9 jNuXDaw6YkAoB4r2ZEpf/M89yEirN66k9BrAhJVEELXzlDpiI+gAXhaRcFVOKcgnq5 H9YjAKBiqMKPv6ZpHQlKfrgjHiMfFCTHhYuuAEXEbJdIF87qgtiAwOBD9XUOdv/sns 3DXVrKeLKxPx7vHcqa6l7rISoEOkAWiLTbnLokv0t2MPq0gbCGoiHt/syRr6iESU5u p/QuVDjW1U3ORNCMGJt66JKDsiK0n+5TmPjKwWzk6p9Wpa7aCVmZG/LRsPQm2nFOl3 aOn7nhSpe5jIA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 204DF180599 for ; Sat, 8 Nov 2025 21:57:25 +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.1 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from fout-b3-smtp.messagingengine.com (fout-b3-smtp.messagingengine.com [202.12.124.146]) (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 ; Sat, 8 Nov 2025 21:57:24 +0000 (UTC) Received: from phl-compute-12.internal (phl-compute-12.internal [10.202.2.52]) by mailfout.stl.internal (Postfix) with ESMTP id 690861D00133 for ; Sat, 8 Nov 2025 16:57:19 -0500 (EST) Received: from phl-imap-05 ([10.202.2.95]) by phl-compute-12.internal (MEProxy); Sat, 08 Nov 2025 16:57:19 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bottled.codes; h=cc:content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1762639039; x=1762725439; bh=8micbt+Dlh rzcS228MEdWazu0myVlZOmX175yO5JYpw=; b=pbkryzjkJj+AsiGwORBa0xhRGi AYlUyp6tD+Pjq1qjd4mvRQcyYTmn0Tz3AS3+N7AiaxDTAvhov9WCF+X2Lq7qmF7f XaQYQdXy0woPIGsl4kUHWA0kcYafH5/HxML75DfkDk64ryUFcJoF1c4wwqi3ppb2 fAot0SVjfuMFoqeeCwlAh3LXCFz7hWLEC6ebl7mulhzheE72VQnc+GGvDo9lJve2 bKRt1GrgyxgouVqgTQvJLO7NElBVOgOHOfIgmhtxtgUpkmOCOKr8gspPwC4KT7GR p3TJo6mN1dCn9dwtMjKPOvQXapw86UzPHCSBb9clbh/MVM43CqPF8+uzYZXA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t= 1762639039; x=1762725439; bh=8micbt+DlhrzcS228MEdWazu0myVlZOmX17 5yO5JYpw=; b=l/zpmSUafZ0Y1+ZEI5/6O5JnlD7WGGx0jC4Kigo7NX2JGBe0Xf5 M1Ldpow/T/wsAMcTAkX1G7PTygbRH7/Z70tjtkPmf8A8MPatBPbaKdeStL9FNUgS j2BkQevcO5scu64lnHdntq6N14JbP9qlRUlX1HPov8VAVOOpwaGSItrX2hBS5ter cu8VwPWTYCiNM90oOxmhnxXtploLkjUNVBCruwlCi339oKRQcS+ylQ+HWFos39Tz j2r2tLcWAbzUyXh8/I0LFDdRGi1j91XdnHVOBOg0jEyKjYkxk+Wx/SfRFoafvMx4 BElAMDyl3u6q/9MERFWQjvYwwIWCdCEcVZQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdeggdduleefieekucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucenucfjughrpefoggffhffvkfgjfhfutgesrgdtreerre dtjeenucfhrhhomhepfdftohgsucfnrghnuggvrhhsfdcuoehrohgssegsohhtthhlvggu rdgtohguvghsqeenucggtffrrghtthgvrhhnpedtueejtdethfeulefhtdelieduteelff dtudelheffgedtieehhfelieejgfevgeenucevlhhushhtvghrufhiiigvpedtnecurfgr rhgrmhepmhgrihhlfhhrohhmpehrohgssegsohhtthhlvggurdgtohguvghspdhnsggprh gtphhtthhopedupdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehinhhtvghrnhgr lhhssehlihhsthhsrdhphhhprdhnvght X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id A60131820054; Sat, 8 Nov 2025 16:57:18 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 X-ThreadId: AZgO4gJIj6HZ Date: Sat, 08 Nov 2025 22:56:07 +0100 To: internals@lists.php.net Message-ID: In-Reply-To: <72f90052-fa19-415c-9f5a-ae75275fd030@rwec.co.uk> References: <72f90052-fa19-415c-9f5a-ae75275fd030@rwec.co.uk> Subject: Re: [PHP-DEV] RFC: Namespace-Scoped Visibility for Methods and Properties Content-Type: multipart/alternative; boundary=82cf21be1589453bba216b0b3dfbdc3a From: rob@bottled.codes ("Rob Landers") --82cf21be1589453bba216b0b3dfbdc3a Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Sat, Nov 8, 2025, at 22:20, Rowan Tommins [IMSoP] wrote: > On 08/11/2025 20:08, Rob Landers wrote: > > The moment we allow "namespace prefixes", we introduce questions tha= t=20 > > need to be fleshed out separately and with care. Do we treat=20 > > "Acme\AuthLib\Session" and "Acme\AuthLib\Services" as related? Even = if=20 > > they come from different vendors and are unrelated in any way? Are=20 > > namespaces hierarchical or just flat strings that happen to contain=20 > > separators? >=20 >=20 > While I appreciate the desire to keep things simple, I don't think we=20 > can avoid asking those questions, we can only propose answers. In your=20 > current RFC, the answers are: >=20 > - No two namespaces are related, even if their names imply a hierarchy. > - Two "internal" classes in the same namespace can see each other even=20 > if they are written by different vendors. >=20 >=20 > > Today namespaces are a name resolution mechanism, not a semantic=20 > > hierarchy. Matching by prefix would start treating them as a package=20 > > system, and I explicitly am trying to avoid that in this RFC. >=20 > I don't think that's true. The language already recognises the namespa= ce=20 > separator, and that if you are in namespace "Acme\AuthLib", an=20 > unqualified reference to "Services\SessionManager" refers=20 > to "Acme\AuthLib\Services\SessionManager". That doesn't require any=20 > concept of "package", but it is clearly based on the conception of=20 > namespaces as a hierarchy. >=20 >=20 > > By restricting the rule to exact namespace equality, the feature is=20 > > straightforward to explain and to understand. It also prevents=20 > > "accidental" access because two unrelated namespaces happen to share= a=20 > > prefix. >=20 > My concern is that by restricting it so much, we would prevent most of=20 > the real-world use cases for it, since the reality is that people use=20 > much more complex namespace hierarchies. >=20 >=20 > > If you have a concrete, unambiguous rule for prefix-based access tha= t=20 > > wouldn=E2=80=99t cause surprises or make assumptions about how peopl= e organise=20 > > their codebases, I=E2=80=99d be happy to discuss it. Right now, ever= y version=20 > > I=E2=80=99ve explored would reopen the "module"/"package" debate fro= m this summer. >=20 > I mentioned, briefly, two possibilities: >=20 > > I think we need a keyword or attribute which takes as a parameter=20 > > either the namespace prefix, or the number of levels to match >=20 > To spell those out, the prefix version could look like this: >=20 > namespace Acme\AuthLib\Somewhere\Deep\In\Package; > // ... > #[NamespacePrivate('Acme\AuthLib', includeChildren: true)] >=20 >=20 > A number of levels version could look like this: >=20 > namespace Acme\AuthLib\Somewhere\Deep\In\Package; > // ... > #[NamespacePrivate(minLevels: 2, maxLevels: null)] >=20 > There's all sorts of variations on how those arguments could be=20 > presented, keywords vs attributes, etc; but the key point is the=20 > language is not defining where the boundary is, it is requiring the us= er=20 > to do so. >=20 >=20 > The prefix-based approach could be expanded into an allow-list that=20 > didn't require any relationship to the current namespace at all: >=20 > namespace Acme\AuthLib\Somewhere\Deep\In\Package; > // ... > #[AllowNamespace('Acme\AuthLib\*')] > #[AllowNamespace('Zeppo\FrameworkCore\*')] >=20 > Or even an allow-deny rule system: >=20 > #[AllowNamespace('Acme\AuthLib\*')] > #[DenyNamespace('Acme\AuthLib\Plugins\*')] >=20 > At that point, it's admittedly rather complex, but it makes *even fewe= r*=20 > assumptions about what constitutes a "package". >=20 >=20 > --=20 > Rowan Tommins > [IMSoP] >=20 Hi Rowan, Thanks for expanding the examples. Those approaches: prefix matching, wildcard matching, level-based matchi= ng, or allow/deny lists are all significantly more expressive than what = this RFC is aiming for. They move the discussion from "namespace -privat= e visibility" into designing a generalised access-control system or a de= -facto package model. That=E2=80=99s a much wider problem space, and wou= ld need its own design work (and, likely, its own RFC). The goal of this RFC is intentionally minimal: take the boundary that al= ready exists in the language (the lexical namespace) and allow private v= isibility to extend across it. Exact namespace equality keeps the rule u= nambiguous, requires no new access-control model, and avoids assumptions= about how developers structure hierarchies. I agree that broader forms of scoping could be useful, but they should b= e in their own proposal. One advantage of keeping this RFC small is that= it can be expanded later without a BC break. For example, prefix matchi= ng (maybe something like `private(namespace: Acme\AuthLib)`) or a protec= ted-namespace variant could be layered on top if the community wants to = go in that direction. This RFC isn=E2=80=99t intended to solve the entire space; it=E2=80=99s = the smallest useful step that seems to fairly cleanly fit into PHP=E2=80= =99s current model without too much churn on the engine. =E2=80=94 Rob --82cf21be1589453bba216b0b3dfbdc3a Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable


On Sat, Nov 8, 2025, at 22:20, Rowan Tommins [IMSoP] w= rote:
On 08/11/= 2025 20:08, Rob Landers wrote:
> The moment we allow "names= pace prefixes", we introduce questions that 
> need to= be fleshed out separately and with care. Do we treat 
&g= t; "Acme\AuthLib\Session" and "Acme\AuthLib\Services" as related? Even i= f 
> they come from different vendors and are unrelate= d in any way? Are 
> namespaces hierarchical or just f= lat strings that happen to contain 
> separators?


While I appreciate the desire to kee= p things simple, I don't think we 
can avoid asking those= questions, we can only propose answers. In your 
current= RFC, the answers are:

- No two namespaces are = related, even if their names imply a hierarchy.
- Two "interna= l" classes in the same namespace can see each other even 
if they are written by different vendors.


=
> Today namespaces are a name resolution mechanism, not a = semantic 
> hierarchy. Matching by prefix would start = treating them as a package 
> system, and I explicitly= am trying to avoid that in this RFC.

I don't t= hink that's true. The language already recognises the namespace 
separator, and that if you are in namespace "Acme\AuthLib", an&n= bsp;
unqualified reference to "Services\SessionManager" refers=  
to "Acme\AuthLib\Services\SessionManager". That do= esn't require any 
concept of "package", but it is clearl= y based on the conception of 
namespaces as a hierarchy.<= /div>


> By restricting the rule to = exact namespace equality, the feature is 
> straightfo= rward to explain and to understand. It also prevents 
>= ; "accidental" access because two unrelated namespaces happen to share a=  
> prefix.

My concern is tha= t by restricting it so much, we would prevent most of 
th= e real-world use cases for it, since the reality is that people use = ;
much more complex namespace hierarchies.


> If you have a concrete, unambiguous rule for p= refix-based access that 
> wouldn=E2=80=99t cause surp= rises or make assumptions about how people organise 
>= their codebases, I=E2=80=99d be happy to discuss it. Right now, every v= ersion 
> I=E2=80=99ve explored would reopen the "modu= le"/"package" debate from this summer.

I mentio= ned, briefly, two possibilities:

> I think w= e need a keyword or attribute which takes as a parameter 
> either the namespace prefix, or the number of levels to match

To spell those out, the prefix version could look l= ike this:

namespace Acme\AuthLib\Somewhere\Deep= \In\Package;
// ...
#[NamespacePrivate('Acme\AuthLib= ', includeChildren: true)]


A num= ber of levels version could look like this:

nam= espace Acme\AuthLib\Somewhere\Deep\In\Package;
// ...
#[NamespacePrivate(minLevels: 2, maxLevels: null)]

There's all sorts of variations on how those arguments could be&nb= sp;
presented, keywords vs attributes, etc; but the key point = is the 
language is not defining where the boundary is, i= t is requiring the user 
to do so.


The prefix-based approach could be expanded into an al= low-list that 
didn't require any relationship to the cur= rent namespace at all:

 namespace Acme\Aut= hLib\Somewhere\Deep\In\Package;
// ...
#[AllowNamesp= ace('Acme\AuthLib\*')]
#[AllowNamespace('Zeppo\FrameworkCore\*= ')]

Or even an allow-deny rule system:

#[AllowNamespace('Acme\AuthLib\*')]
#[DenyNam= espace('Acme\AuthLib\Plugins\*')]

At that point= , it's admittedly rather complex, but it makes *even fewer* 
<= div>assumptions about what constitutes a "package".

=

-- 
Rowan Tommins
[IMSoP]


Hi Rowan,
=
Thanks for expanding the examples.

Those approaches: prefix matching, wildcard matching, level-based mat= ching, or allow/deny lists are all significantly more expressive than wh= at this RFC is aiming for. They move the discussion from "namespace -pri= vate visibility" into designing a generalised access-control system or a= de-facto package model. That=E2=80=99s a much wider problem space, and = would need its own design work (and, likely, its own RFC).
The goal of this RFC is intentionally minimal: take the boun= dary that already exists in the language (the lexical namespace) and all= ow private visibility to extend across it. Exact namespace equality keep= s the rule unambiguous, requires no new access-control model, and avoids= assumptions about how developers structure hierarchies.

<= /div>
I agree that broader forms of scoping could be useful, but the= y should be in their own proposal. One advantage of keeping this RFC sma= ll is that it can be expanded later without a BC break. For example, pre= fix matching (maybe something like `private(namespace: Acme\AuthLib)`) o= r a protected-namespace variant could be layered on top if the community= wants to go in that direction.

This RFC isn=E2= =80=99t intended to solve the entire space; it=E2=80=99s the smallest us= eful step that seems to fairly cleanly fit into PHP=E2=80=99s current mo= del without too much churn on the engine.

=E2=80=94 Rob
--82cf21be1589453bba216b0b3dfbdc3a--