On Wed, Apr 29, 2026, at 12:30 PM, Daniel Scherzer wrote: > Hi internals, > > I'd like to add support for friendship in PHP. I don't mean friendship > in the PSR-8 huggable way,
Aw, but why not? > but rather in the C++ way of allowing access > to non-public parts of a class without needing to use Reflection. > > I haven't started work on implementing this yet, but there is a big > question about how to indicate friendship that I wanted to get some > feedback on. Specifically, should it be added with a new keyword, or > with an attribute? > > Keyword > * matches C++ > * suggests that friends are aspects of the class, like properties and > constants and methods > * but would look a bit ugly if we added support for friends that are > just for specific properties/methods/constants > > Attribute > * matches how other metadata is added to classes > * would make it look cleaner if subsequently support was added for > friendship being applied to specific properties/methods/constants > * would differ from the current builtin attributes in that it doesn't > just add/remove warnings, but changes some functionality > > For a more in-depth explanation of the inspiration and these two > potential approaches, see > https://scherzer.dev/Blog/20260309-php-friends. To be clear, I have not > yet written an implementation, much less the RFC, but I wanted to get > some initial feedback on if people would prefer a new keyword, or an > attribute, for declaring friends. > > -Daniel There was a lot of related discussion around module/package/file visibility not too long ago that is also worth reviewing. Currently I am highly skeptical of friend classes, as I believe module-level visibility is more useful than class-level, in general. That said, were we to go this route, I agree that keywords would be the way to go for the reasons given in the blog post. Also, there's some plumbing already i place via aviz, at least for properties. In concept, the following should be possible: class User { friend UserFactory; public friend(set) string $name; } class UserFactory { public function makeUser($name) { $u = new User(); $u->name = $name; // This is OK, because UserFactory is a friend. return $u; } } $factory = new UserFactory(); $u = $factory->makeUser('Larry'); print $u->name; // OK, because public get $u->name = 'Daniel'; // Error, because not a friend. Whether that makes sense to extend to methods, I don't know. --Larry Garfield
