Hi,
I know the subject was discussed years ago, and it was decided not to
implement 'friend class' declarations (see
https://bugs.php.net/bug.php?id=34044).
But the discussions occurred ten years ago, and things (and people) may be
different now.
Unfortunately, there is no easy-to-use and fast solution for this yet. Most
projects have asked for such a feature for years but, till now, they still
have to rely on a big warning in the documentation. Some, like symfony, also
add an '@internal' tag in their phpdoc block. This can be checked in an IDE
but that's information, not access restriction.
IMHO, such a feature would be a valuable addition for PHP 7. If you agree, I
will write an RFC.
The feature I was thinking about would be globally similar to C++ friend
classes, except that a PHP friend class would have access to protected
resources, but not private ones (private would remain private).
The inheritance rules would be similar to C++ rules (adapted from Wikipedia
as it originally includes access to private resources) :
-
Friendships are not symmetric If class A is a friend of class B, class B
is not automatically a friend of class A. -
Friendships are not transitive If class A is a friend of class B, and
class B is a friend of class C, class A is not automatically a friend of
class C. -
Friendships are not inherited A friend of class Base is not
automatically a friend of class Derived and vice versa; equally if Base is a
friend of another class, Derived is not automatically a friend and vice
versa. -
Access due to friendship is inherited A friend of Derived can access the
protected members of Derived that were inherited from Base (simpler than the
C++ rule as friend classes and derived classes have the same access rights).
Another idea would be to base access restriction on namespaces, but, IMO,
namespaces would not bring the precision we need : each class needs to
define which classes are accepted as 'friends'.
Please comment.
Regards,
François
Hi,
I know the subject was discussed years ago, and it was decided not to
implement 'friend class' declarations (see
https://bugs.php.net/bug.php?id=34044).But the discussions occurred ten years ago, and things (and people) may be
different now.Unfortunately, there is no easy-to-use and fast solution for this yet. Most
projects have asked for such a feature for years but, till now, they still
have to rely on a big warning in the documentation. Some, like symfony,
also
add an '@internal' tag in their phpdoc block. This can be checked in an IDE
but that's information, not access restriction.IMHO, such a feature would be a valuable addition for PHP 7. If you agree,
I
will write an RFC.The feature I was thinking about would be globally similar to C++ friend
classes, except that a PHP friend class would have access to protected
resources, but not private ones (private would remain private).The inheritance rules would be similar to C++ rules (adapted from Wikipedia
as it originally includes access to private resources) :
Friendships are not symmetric – If class A is a friend of class B, class
B
is not automatically a friend of class A.Friendships are not transitive – If class A is a friend of class B, and
class B is a friend of class C, class A is not automatically a friend of
class C.Friendships are not inherited – A friend of class Base is not
automatically a friend of class Derived and vice versa; equally if Base is
a
friend of another class, Derived is not automatically a friend and vice
versa.Access due to friendship is inherited – A friend of Derived can access
the
protected members of Derived that were inherited from Base (simpler than
the
C++ rule as friend classes and derived classes have the same access
rights).Another idea would be to base access restriction on namespaces, but, IMO,
namespaces would not bring the precision we need : each class needs to
define which classes are accepted as 'friends'.Please comment.
Regards,
François
There is no need for friend classes in order to support this kind of
feature (see
http://ocramius.github.io/blog/accessing-private-php-class-members-without-reflection/
)
Except for voodoo-cases (AOP frameworks and such) I don't see much of a
use-case here.
If you need to sync up properties between two classes you can do so by
simply using closures, as I described above.
Otherwise, making properties public
and marking them as @internal DO NOT TOUCH THIS!
is perfectly fine, and doesn't need language-level
restrictions IMO.
If you need this sort of feature, consider looking at the recently
discussed https://github.com/php/php-src/pull/947, which is really much
more useful and less magic :-)
Greets,
Marco Pivetta