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

Reply via email to