Re: Re: [RFC] [Discussion] Friends

From: Date: Mon, 08 Jun 2026 18:42:00 +0000
Subject: Re: Re: [RFC] [Discussion] Friends
References: 1 2 3 4  Groups: php.internals 
Request: Send a blank email to internals+get-131172@lists.php.net to get a copy of this message
On Mon, Jun 8, 2026 at 2:19 AM Tim Düsterhus <tim@bastelstu.be> 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

« previous php.internals (#131172) next »