PHP inheritance and protected member visibility
inheritance, php
Solution
You can access those methods because there is a declaration of them as protected in `Foo`, which is your parent and that gives you permission to access it. If you remove the declaration from the parent and declare the protected method in `B` you will get a Fatal Error.
This is reported as a bug in PHP https://bugs.php.net/bug.php?id=50892
Problem
I've found something that appears to be a strange inheritance issue in PHP. From the PHP manual: Members declared protected can be accessed only within the class itself and by inherited and parent classes. To me this means: A can access the protected members of B if `A instanceof B` or `B instanceof A`. However, if both A and B extend Foo, and Foo has a protected constructor which is not overwritten in B, then I can create an instance of B from within A. This does not make sense to me, because A is not an instance of B and B is not an instance of A. I can also call the protected method `$b->test()` from within A, which executes the method implemented in B. (If B does not redeclare `test()` then the implementation in Foo is executed.) To me this is even more strange because I cannot create an instance of B from within A if B directly implements a protected constructor. It seems strange that I cannot access a protected constructor (also declared in the parent class) but accessing a protected method (also declared in the parent class) is no problem. Note that I do get the expected behavior when I use a class C which does not extend Foo. If I try to instantiate B from within C, I get a fatal error because I'm trying to access a protected constructor. If I add a public constructor to B it is possible to instantiate it (which is expected) and I still cannot access the protected method `test()` (this is also expected behavior). I expect the same behavior when using A instead of C. Sample code which explains again: ``` class Foo { protected function __construct() { echo('Constructing ' . get_called_class()); } protected function test() { echo('Hello world ' . __METHOD__); } } class A extends Foo { public function __construct() { parent::__construct(); } public function testB() { // Both of these lines work $b = new B(); $b->test(); } } class B extends Foo { protected function test() { echo('Hello world Again ' . __METHOD__); } } class C { public function __construct() { } public function testB() { // Both of these lines cause fatal errors $b = new B(); $b->test(); } } $a = new A(); $a->testB(); $c = new C(); $c->testB(); ``` I'm probably not seeing something, but I can't find what. Could anyone explain the behavior to me?