I did "RTFM" and I understand that protected members are not SUPPOSED TO BE ABLE to be accessed from anything but "within the class itself and by inherited and parent classes." The bug is that, when the calling scope resolves and LOOKS LIKE the correct scope because it is an inherited class, but is a _different inherited class_ of the same parent object in which the protected member was declared, the engine allows access to protected members from OUTSIDE THE CLASS.
In the example, both "bar" and "kid" extend foo, but "kid" should NOT have access to bar's protected members, but it does, but its resolving scope looks similar to the correct scope that would need to resolve.
This isn't an RTFM issue, it's a legitimate bug. Did you read the reproduce code?

At a second glance, it really looks like it is wrong.
The visibility check should also be based on the object from which the
properties are read.
As for my "it works that way in Java" argument, it contradicts the java
specifications:
http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.6.2.1
and hence is invalid. (Thanks oorza for pointing that out)
There is no design ground to accept that, it is a bug. The question that
remains is: is it worth to fix BC-wise?

[2010-05-06 21:39 UTC] php at b8r dot org

It causes more problems then the original poster notes. We've run into problems using __get and __set. Since php see's the member as "in scope" for both classes, the __get and __set methods don't get called.

normandiggs, your sample is irrelevant.
It's ok to access private and protected properties from same type object.
It's bad to access protected properties from different type object.
Why I hate this behavior:
http://3v4l.org/tiOC5 - we receive protected value
http://3v4l.org/uT9PC - we receive fatal error
We should not to rely to implementation of B class (see fiddles)
Another note - this behavior was broken in 5.2 version.

A PR was prepared to fix this on the current master (7.2) but it was decided the the potential BC break could possibly be too much for a minor and it was suggested that it should wait for the next major.

> https://3v4l.org/TM6jk
This appears to be exactly the opposite complaint from the original: in this case, the protected property *can't* be accessed in a different child.
So we certainly have an inconsistency here - between methods and properties, and based on whether the member is inherited directly or over-ridden / re-declared. The case of a re-declared property is currently the only one that errors, so the simplest change would be to remove that error.
Class C knows that the access is legal when given an A, so assumes it's valid for all sub-classes of A; sub-class B2 is currently able to break this assumption for a property, but not for a method.

[2018-05-26 16:49 UTC] rowan dot collins at gmail dot com

@giovanni:
Why would the expected behaviour there be to print 10? Re-declaring a property doesn't create a second property with the same name, it changes it polymorphically just like re-declaring a method does. Either the method can see the value 10, or it cannot see any value.
class C {
protected $x = 10;
public function m() {
print "x=" . $this->x . "\n";
}
}
class D extends C {
protected $x = 20;
}
$d = new D();
$d->m(); // "x=20"