On Sun, Nov 9, 2025, at 10:45, Rob Landers wrote: > > > On Sun, Nov 9, 2025, at 07:09, Alexandru Pătrănescu wrote: >> Hi Rob >> >> On Sat, Nov 8, 2025, 14:46 Rob Landers <[email protected]> wrote: >>> __ >>> Hello Internals, >>> >>> I’d like to introduce an RFC for discussion: >>> https://wiki.php.net/rfc/namespace_visibility which proposes a new >>> visibility modifier: private(namespace). >>> >>> This idea has appeared several times in previous threads but never >>> progressed to a formal proposal (from what I could find). My hope is that >>> with defined semantics, examples, and implementation details, we can >>> evaluate it properly and see whether there’s support for moving forward. >>> Feedback is very welcome. >>> >>> >> >> Nice work on this. >> >> >> I have one issue: >> > *Visibility hierarchy: *public < protected < private(namespace) < private >> >>> >> I think is not a correct view of the real problem space, as the protected >> and private namespace scopes are separate sets that might have things in >> common but can also be distinct. >> >> I think the correct way to model it, is to have two hierarchies: >> public < protected < private >> public < private(namespace) < private >> >> Otherwise you can have things like >> `protected private(namespace)(set)` >> that is unclear how it should be handled. >> Can you clarify what is the right-now expected get and set allowance for >> these cases: >> - child classes in the same namespace >> - child classes in another namespace >> - non-child classes in the same namespace >> >> >> My suggestion is to not allow mixing protected and private namespace for >> aviz. >> >> -- >> Alex > > Hi Alex, > > I think you’re right, treating this as a simple linear hierarchy is > misleading. `Protected` and `private(namespace)` *are *based on different > axes: > > - `protected` is inheritance-based > - `private(namespace)` is namespace-based > > So, for `protected private(namespace)`: > - child class in the same namespace: read + write > - child class in a different namespace: read-only > - non-child class in the same namespace: forbidden > > Formally, we can consider the caller sets: > > - C[public] > - C[protected] (declaring class ∪ subclasses) > - C[ns] (all code in the exact declaring namespace) > - C[private] (declaring class only) > > We have two partial orders: > - C[public] ⊇ C[protected] ⊇ C[private] > - C[public] ⊇ C[ns] ⊇ C[private] > > In general, C[protected] and C[ns] are incomparable (neither is a subset of > the other). > > For asymmetric properties, the `(set)` visibility must satisfy C[set] ⊇ > C[base]. If C[set] and C[base] are incomparable or otherwise not a subset, > it’s a compile-time error. > > That yields: > > - `public` with any `(set)` visibility: C[any] ⊆ C[public] > - `protected` with `protected(set)` or `private(set)` only: C[private] ⊆ > C[protected] > - `private(namespace)` with `private(namespace)(set)` or `private(set)` only: > C[private] ⊆ C[ns] > - `private` with `private(set)` only: C[private] ⊆ C[private] > - `protected` with `private(namespace)(set)`: incomparable > - `private` with `private(namespace)(set)`: C[ns] ⊈ C[private] > > I’ll update the RFC to drop the linear hierarchy and update with the subset > rule explicitly with some examples. > > — Rob
I’ve updated the RFC and implementation accordingly along with some editorial changes. — Rob
