[php-src] PR #22969: Resolve the effective property in ReflectionProperty lazy APIs
| From: | iliaal | Date: | Fri, 31 Jul 2026 13:26:52 +0000 |
| Subject: | [php-src] PR #22969: Resolve the effective property in ReflectionProperty lazy APIs | ||
| Groups: | php.git-pulls | ||
| Request: | Send a blank email to git-pulls+get-37410@lists.php.net to get a copy of this message | ||
Pull Request: https://github.com/php/php-src/pull/22969
Author: iliaal
ReflectionProperty::skipLazyInitialization() and isLazy() index the object with
ref->prop, the property info of the reflected scope. When a child class adds hooks to a plain
parent property, inheritance gives the child its own storage slot and leaves the parent slot
IS_UNDEF, so a parent-scoped ReflectionProperty reads and writes the dead slot: isLazy() answers
false and skipLazyInitialization() is a silent no-op. getRawValue(), setRawValue() and
setRawValueWithoutLazyInitialization() already resolve the effective property through
reflection_property_get_effective_prop(), and these two now do the same.
```php
class B { public $b = 1; }
class C extends B { public $b { get => $this->b; set => $this->b = $value; } }
$reflector = new ReflectionClass(C::class);
$obj = $reflector->newLazyGhost(function ($obj) { $obj->b = 9; });
var_dump((new ReflectionProperty(B::class, 'b'))->isLazy($obj)); // false, should be
true
var_dump((new ReflectionProperty(C::class, 'b'))->isLazy($obj)); // true
```
Private parent properties still resolve to the declaring scope's slot, and static or virtual
effective properties still return false or throw.