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 that
> > need to be fleshed out separately and with care. Do we treat
> > "Acme\AuthLib\Session" and "Acme\AuthLib\Services" as related? Even if
> > they come from different vendors and are unrelated in any way? Are
> > namespaces hierarchical or just flat strings that happen to contain
> > separators?
>
>
> While I appreciate the desire to keep 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 "internal" 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 think that's true. The language already recognises the namespace
> separator, and that if you are in namespace "Acme\AuthLib", an
> unqualified reference to "Services\SessionManager" refers
> to "Acme\AuthLib\Services\SessionManager". That doesn't require any
> concept of "package", but it is clearly based on the conception of
> namespaces as a hierarchy.
>
>
> > By restricting the rule to exact namespace equality, the feature is
> > straightforward to explain and to understand. It also prevents
> > "accidental" access because two unrelated namespaces happen to share a
> > prefix.
>
> My concern is that by restricting it so much, we would prevent most of
> the 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 prefix-based access that
> > wouldn’t cause surprises or make assumptions about how people organise
> > their codebases, I’d be happy to discuss it. Right now, every version
> > I’ve explored would reopen the "module"/"package" debate from this summer.
>
> I mentioned, briefly, two possibilities:
>
> > I think we 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 like this:
>
> namespace Acme\AuthLib\Somewhere\Deep\In\Package;
> // ...
> #[NamespacePrivate('Acme\AuthLib', includeChildren: true)]
>
>
> A number of levels version could look like this:
>
> namespace Acme\AuthLib\Somewhere\Deep\In\Package;
> // ...
> #[NamespacePrivate(minLevels: 2, maxLevels: null)]
>
> There's all sorts of variations on how those arguments could be
> presented, keywords vs attributes, etc; but the key point is the
> language is not defining where the boundary is, it is requiring the user
> to do so.
>
>
> The prefix-based approach could be expanded into an allow-list that
> didn't require any relationship to the current namespace at all:
>
> namespace Acme\AuthLib\Somewhere\Deep\In\Package;
> // ...
> #[AllowNamespace('Acme\AuthLib\*')]
> #[AllowNamespace('Zeppo\FrameworkCore\*')]
>
> Or even an allow-deny rule system:
>
> #[AllowNamespace('Acme\AuthLib\*')]
> #[DenyNamespace('Acme\AuthLib\Plugins\*')]
>
> At that point, it's admittedly rather complex, but it makes *even fewer*
> assumptions about what constitutes a "package".
>
>
> --
> Rowan Tommins
> [IMSoP]
>
Hi Rowan,
Thanks for expanding the examples.
Those approaches: prefix matching, wildcard matching, level-based matching, or
allow/deny lists are all significantly more expressive than what this RFC is
aiming for. They move the discussion from "namespace -private visibility" into
designing a generalised access-control system or a de-facto package model.
That’s 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 boundary that already
exists in the language (the lexical namespace) and allow private visibility to
extend across it. Exact namespace equality keeps the rule unambiguous, 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 be 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 matching (maybe
something like `private(namespace: Acme\AuthLib)`) or a protected-namespace
variant could be layered on top if the community wants to go in that direction.
This RFC isn’t intended to solve the entire space; it’s the smallest useful
step that seems to fairly cleanly fit into PHP’s current model without too much
churn on the engine.
— Rob