Edit report at https://bugs.php.net/bug.php?id=62045&edit=1
ID: 62045
Comment by: anon at anon dot anon
Reported by: gonzalo123 at gmail dot com
Summary: public access to a protected method
Status: Not a bug
Type: Bug
Package: Class/Object related
Operating System: Linux
PHP Version: 5.3.13
Block user comment: N
Private report: N
New Comment:
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").
Previous Comments:
------------------------------------------------------------------------
[2012-05-16 14:21:36] [email protected]
read: "is the same in"
------------------------------------------------------------------------
[2012-05-16 14:14:39] [email protected]
Right. But it doesn't change anything. The type is only important to decide
what the foo() method is, and foo() is AnotherClass and OneClass.
------------------------------------------------------------------------
[2012-05-16 13:15:57] gonzalo123 at gmail dot com
$this->object is not an instance of OneClass.
$this->object is an instance of AnotherClass (look at the constructor).
------------------------------------------------------------------------
[2012-05-16 11:36:49] [email protected]
$this->object is an instance of OneClass. $this->object->foo() is called. foo()
is protected and was defined in the context of OneClass. The access is done in
the context of AnotherClass. AnotherClass is a subclass of OneClass (the
context where foo() was defined). Therefore access is granted. I don't know
what's your problem here.
------------------------------------------------------------------------
[2012-05-16 09:00:32] gonzalo123 at gmail dot com
But we are not accesing OneClass::foo. This access is allowed beacause of the
extends,we should not have access to use $this->object->foo();
$this is an instance of OneClass (it extends AnotherClass) but $this->object
(we
load it with DI) is an instance of AnotherClass. foo is protected here and we
are
accesing as a public method.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=62045
--
Edit this bug report at https://bugs.php.net/bug.php?id=62045&edit=1