Bug #66670 [Nab]: property_exist cannot find private properties defined in superclass
| From: | requinix@php.net | Date: | Tue, 11 Feb 2014 01:10:14 +0000 |
| Subject: | Bug #66670 [Nab]: property_exist cannot find private properties defined in superclass | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-184251@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=66670&edit=1
ID: 66670
Updated by: requinix@php.net
Reported by: mpope at homeimprovementleads dot com
Summary: property_exist cannot find private properties
defined in superclass
Status: Not a bug
Type: Bug
Package: Class/Object related
Operating System: windows 7
PHP Version: 5.5.9
Block user comment: N
Private report: N
New Comment:
Re: third reply
You're right in that it would belong in a separate ticket, but I don't think your code is
quite as you've described.
<?php
class ParentClass {
private $foo = 123;
function __call($method, $args) { var_dump($this->$method); }
}
class ChildClass extends ParentClass {
private $bar = 456;
}
echo "Parent:\n";
$p = new ParentClass();
$p->foo(); $p->bar();
echo "\nChild:\n";
$c = new ChildClass();
$c->foo(); $c->bar();
// Parent:
// int(123)
// NULL
// Child:
// int(123)
// Fatal error: Cannot access private property ChildClass::$bar...
?>
Previous Comments:
------------------------------------------------------------------------
[2014-02-11 01:01:17] requinix@php.net
Re: first two replies
I think what you're missing is that even though $foo and $goo are not inherited and don't
"exist" in $this, they must clearly exist *somewhere* for A and B to be able to use them.
Here's three simple statements, all restating the same underlying rule:
1. $this->foo exists in an instance of A (1a) and in code inherited from A (1b)
2. $this->goo exists in an instance of B (2a) and in code inherited from B (2b)
3. $this->poo exists in an instance of C (3a) and in code inherited from C (3b)
They fully explain the output:
// C::__construct
bool(false) // $foo: neither 1a nor 1b apply
bool(false) // $goo: neither 2a nor 2b apply
bool(true) // $poo: both 3a and 3b apply
// B::__construct
bool(false) // $foo: neither 1a nor 1b apply
bool(true) // $goo: 2a does not apply but 2b does
bool(true) // $poo: 3a applies (3b does not)
// A::__construct
bool(true) // $foo: 1a does not apply but 1b does
bool(false) // $goo: neither 2a nor 2b apply
bool(true) // $poo: 3a applies (3b does not)
// check_scope
bool(false) // $foo: neither 1a nor 1b apply
bool(false) // $goo: neither 2a nor 2b apply
bool(true) // $poo: 3a applies (3b does not)
------------------------------------------------------------------------
[2014-02-11 00:19:14] mpope at homeimprovementleads dot com
And this might be worthy of its own ticket, but it looks like all magic methods use an incorrect
scope during execution. I have a __call() method that cannot access a private property declared in
the same class when __call() is invoked via a subclassed object.
In the context of the example script, if class 'a' had a __call() method defined and we
called $c->UnknownFunc(), the __call method in class 'a' would not be able to access
$foo, even though they're in the same class. And yet with $c->UnknownFunc() I can access
$poo from class a's __call() method even though $poo is defined in class 'c', not
class 'a' where the __call method is defined.
------------------------------------------------------------------------
[2014-02-10 23:22:52] mpope at homeimprovementleads dot com
Additionally if we're going to be strict to inheritance rules about private properties, we
shouldn't see private properties of our subclasses either. Just the private properties of the
currently scoped class. But in the example you'll notice that property_exist returns true for
both the current class's scope AND the 'c' subclass. Meaning in class a's
constructor I can see two private properties, $foo and $poo. By your statement I should only see
$foo.
------------------------------------------------------------------------
[2014-02-10 23:11:00] mpope at homeimprovementleads dot com
Ok, but there is still a bug in that if you call property_exists from the class proper, vs from some
externally defined method from the class you get different results. In the example I posted, the
check_scope() function should echo the same results as the explicit checks inside the constructors.
------------------------------------------------------------------------
[2014-02-08 00:31:50] requinix@php.net
It's a matter of inheritance, not accessibility: the subclasses do not inherit the private
properties of the superclasses. The properties really don't exist.
------------------------------------------------------------------------
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=66670
--
Edit this bug report at https://bugs.php.net/bug.php?id=66670&edit=1