Bug #66670 [Nab]: property_exist cannot find private properties defined in superclass

From: 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

« previous php.bugs (#184251) next »