diff --git a/NEWS b/NEWS index 0c506b6349b..4408608a5dd 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.4.6 +- Core: + . Fixed property hook backing value access in multi-level inheritance. + (ilutov) 27 Feb 2025, PHP 8.4.5 diff --git a/Zend/tests/property_hooks/multi_level_inheritance.phpt b/Zend/tests/property_hooks/multi_level_inheritance.phpt new file mode 100644 index 00000000000..a41a32fd71f --- /dev/null +++ b/Zend/tests/property_hooks/multi_level_inheritance.phpt @@ -0,0 +1,70 @@ +--TEST-- +Property hooks with multi level inheritance +--FILE-- + parent::$prop::get() * 2; } +} + +class C extends B { + public $prop = 3; +} + +function test(A $a) { + var_dump($a); + var_dump((array)$a); + var_dump(unserialize(serialize($a))); + var_dump(get_object_vars($a)); + var_dump(json_decode(json_encode($a))); +} + +test(new B); +test(new C); + +?> +--EXPECTF-- +object(B)#%d (1) { + ["prop"]=> + int(2) +} +array(1) { + ["prop"]=> + int(2) +} +object(B)#%d (1) { + ["prop"]=> + int(2) +} +array(1) { + ["prop"]=> + int(4) +} +object(stdClass)#%d (1) { + ["prop"]=> + int(4) +} +object(C)#%d (1) { + ["prop"]=> + int(3) +} +array(1) { + ["prop"]=> + int(3) +} +object(C)#%d (1) { + ["prop"]=> + int(3) +} +array(1) { + ["prop"]=> + int(6) +} +object(stdClass)#%d (1) { + ["prop"]=> + int(6) +} diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 9a1314682ce..e41ad1405e4 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -1436,7 +1436,7 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke } if (!(parent_info->flags & ZEND_ACC_PRIVATE)) { if (!(parent_info->ce->ce_flags & ZEND_ACC_INTERFACE)) { - child_info->prototype = parent_info; + child_info->prototype = parent_info->prototype; } if (UNEXPECTED((parent_info->flags & ZEND_ACC_STATIC) != (child_info->flags & ZEND_ACC_STATIC))) {