On Mon, Jun 8, 2026 at 2:19 AM Tim Düsterhus <[email protected]> wrote:

> Hi
>
> Am 2026-06-04 01:13, schrieb Daniel Scherzer:
> > Seeing no further feedback, I have adjusted the RFC and the
> > implementation
> > to only allow access to protected properties/methods/constants.
> > This qualifies as a "major change" and triggers a 14 day cooldown
> > period.
>
> I've given the RFC another read and stumbled over:
>
> > Friendship is not inherited. If UserFactory has a subclass
> > NamedUserFactory, that subclass cannot access the protected details of
> > User
>
>  From what I see this would also be in violation of the LSP, because
> subclasses are not fully interchangeable with the top-level class. It
> would also need clarification what the relevant “authority” for
> accessibility is: Is it the class name of the actual class or is it the
> defining class of the method in question?
>
> i.e.
>
>      class User { friend UserFactory; protected function __construct() {
> } }
>
>      class UserFactory {
>          public function foo() { new User(); }
>      }
>
>      class ChildUserFactory extends UserFactory { }
>
>      $f = new ChildUserFactory();
>      $f->foo(); // Is this legal? ChildUserFactory is not a friend, but
> foo() is defined in UserFactory.
>
> Best regards
> Tim Düsterhus
>


Since `foo()` is defined in `UserFactory` rather than `ChildUserFactory`,
the method call still works - I was going to go add a test for this, but I
already have one, see
https://github.com/DanielEScherzer/php-src/blob/9f3c8dcac5032f11cf8b8c0ee6a4a2611a2a3933/Zend/tests/friends/not_inherited.phpt

Specifically, friendship is checked based on where the caller is *defined*,
i.e. for inherited methods (here ChildUserFactory::foo(), in my test
Baz::testFooAccess()) the parent class which defines the function is what
needs to be a friend.

I've added this clarification to the RFC text with a clearer example (and
updated the implementation with the new example test) - even when `foo()`
is overridden, using `parent::foo()` would work. As long as the actual
access is done from code defined in a friend, things work.

Let me know if the updated RFC text is still unclear.

-Daniel

Reply via email to