|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2014-02-08 00:15 UTC] mpope at homeimprovementleads dot com
Description: ------------ Despite reporting as fixed ( https://bugs.php.net/bug.php?id=50810 ) and closed in 5.3.3 according to the change log, a small variation in the logic still produces a bug in 5.5.9. The fix in 50810 only worked because the method checking the private property was in the same class as the private property. If you attempt to check the private property of a superclass from the subclass it reports false. Although I would normally expect this behavior, I think it is counter to the statement found in the docs for property_exists in the change log section: "5.3.0 This function checks the existence of a property independent of accessibility." Test script: --------------- <?php function check_scope($ref) { echo "vs\n"; var_dump(property_exists($ref, 'foo')); var_dump(property_exists($ref, 'goo')); var_dump(property_exists($ref, 'poo')); echo "\n"; } class a { private $foo; public function __construct() { var_dump(property_exists($this, 'foo')); var_dump(property_exists($this, 'goo')); var_dump(property_exists($this, 'poo')); check_scope($this); } } class b extends a { private $goo; public function __construct() { var_dump(property_exists($this, 'foo')); var_dump(property_exists($this, 'goo')); var_dump(property_exists($this, 'poo')); check_scope($this); parent::__construct(); } } class c extends b { private $poo; public function __construct() { var_dump(property_exists($this, 'foo')); var_dump(property_exists($this, 'goo')); var_dump(property_exists($this, 'poo')); check_scope($this); parent::__construct(); } } new c(); Expected result: ---------------- Given the accessibility consideration I would expect property_exists to return true in all of the cases outlined in the test script. However, running the script will show that property existence checks depend on both the location of the private variable definition AND the location of the property_exists method call. The results in the check_scope() method do not match the results of the same logic copy and pasted into each constructor method. Actual result: -------------- bool(false) bool(false) bool(true) vs bool(false) bool(false) bool(true) bool(false) bool(true) bool(true) vs bool(false) bool(false) bool(true) bool(true) bool(false) bool(true) vs bool(false) bool(false) bool(true) PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2026 The PHP GroupAll rights reserved. |
Last updated: Tue Oct 06 21:00:01 2026 UTC |
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... ?>Going "off the record", so to speak: Roughly, yes. I don't know the internal implementation of inheritance, I haven't found anything online talking about it, and I don't want to spelunk through the source looking to understand it, however I would suspect something simpler than a "temporal privilege" system. As for reflecting the property, it is possible if you go through the parent class for it. Using the ParentClass/ChildClass example I posted, <?php $rc = new ReflectionClass($c); $rp = $rc->getParentClass(); // or $rp = new ReflectionClass("ParentClass") if you know that already $foo = $rp->getProperty("foo"); // then you can, eg, get the value with $foo->setAccessible(true); // since $foo is private echo $foo->getValue($c); // passing an instance of the child ?>