| 
        php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
  [2012-05-16 08:23 UTC] gonzalo123 at gmail dot com
 Description:
------------
This code works, but it shouldn't, because AnotherClass::foo is protected.
It works only if "OneClass" extends "AnotherClass". If we dont't extends 
"OneClass" with "AnotherClass" (in this example we don't need it) we will see the 
normal error:
Fatal error: Call to protected method AnotherClass::foo() from context 'OneClass'
Test script:
---------------
class AnotherClass {
    protected function foo() {
        return "bar";
    }
}
class OneClass extends AnotherClass {
    private $object;
    public function __construct(AnotherClass $object) {
        $this->object = $object;
    }
    public function myFunction() {
        return $this->object->foo();
    }
}
$obj = new OneClass(new AnotherClass());
echo $obj->myFunction();
Expected result:
----------------
Fatal error: Call to protected method AnotherClass::foo() from context 'OneClass'
Actual result:
--------------
"bar" (without Fatal error)
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             
             | 
    |||||||||||||||||||||||||||
            
                 
                Copyright © 2001-2025 The PHP GroupAll rights reserved.  | 
        Last updated: Tue Nov 04 08:00:01 2025 UTC | 
Here is another case which shows access granted based on class and not instance: $a = new A(); $a->other = new A(); $a->foo(); class A { var $other; private function bar() {} public function foo() { $this->other->bar(); // okay to access private member of other instance of the same class } } It's definitely a desirable feature in this case, because it allows public static factory methods with private constructors. I can't think of a simple use for the subclass protected access though. The PHP manual states "Members declared protected can be accessed only within the class itself and by inherited and parent classes. Members declared as private may only be accessed by the class that defines the member." (http://php.net/manual/en/language.oop5.visibility.php), so this is at least working as documented. Note the terminology: "class", not "instance of class". Even if a rule change was desirable it couldn't be done without breaking backward compatibility. I translated both code samples here to Java and C++ to get a second opinion, as it were. In Java, both are allowed (see here for the rule on protected access: http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.2.1). In C++, the second example with private access from the same class is allowed; however the protected example given in the original report is not ("error: 'const char* AnotherClass::foo()' is protected").