diff --git a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_initialized.phpt b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_initialized.phpt index caa5211f371a5..25580b32ae2cc 100644 --- a/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_initialized.phpt +++ b/Zend/tests/lazy_objects/setRawValueWithoutLazyInitialization_initialized.phpt @@ -17,6 +17,7 @@ function test(string $name, object $obj) { $reflector->initializeLazyObject($obj); $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, 'test'); + var_dump($obj->a); var_dump($obj); } @@ -33,9 +34,22 @@ $obj = $reflector->newLazyProxy(function () { test('Proxy', $obj); +$real = new C('foo'); +$obj = $reflector->newLazyProxy(function () use ($real) { + return $real; +}); +$reflector->initializeLazyObject($obj); +$reflector->resetAsLazyProxy($real, function () { + return new C('bar'); +}); +$reflector->initializeLazyObject($real); + +test('Nested Proxy', $obj); + ?> --EXPECTF-- # Ghost +string(4) "test" object(C)#%d (2) { ["a"]=> string(4) "test" @@ -43,12 +57,27 @@ object(C)#%d (2) { NULL } # Proxy +string(4) "test" lazy proxy object(C)#%d (1) { ["instance"]=> object(C)#%d (2) { ["a"]=> - NULL + string(4) "test" ["b"]=> NULL } } +# Nested Proxy +string(4) "test" +lazy proxy object(C)#%d (1) { + ["instance"]=> + lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + string(4) "test" + ["b"]=> + NULL + } + } +} diff --git a/Zend/tests/lazy_objects/skipLazyInitialization_initialized_object.phpt b/Zend/tests/lazy_objects/skipLazyInitialization_initialized_object.phpt index bf8ff2094ca15..8c2a52de53511 100644 --- a/Zend/tests/lazy_objects/skipLazyInitialization_initialized_object.phpt +++ b/Zend/tests/lazy_objects/skipLazyInitialization_initialized_object.phpt @@ -36,6 +36,19 @@ $obj = $reflector->newLazyProxy(function () { test('Proxy', $obj); +$real = new C('foo'); +$obj = $reflector->newLazyProxy(function () use ($real) { + return $real; +}); +$reflector->initializeLazyObject($obj); +$reflector->resetAsLazyProxy($real, function () { + var_dump("initializer"); + return new C('bar'); +}); +$reflector->initializeLazyObject($real); + +test('Nested Proxy', $obj); + ?> --EXPECTF-- # Ghost @@ -48,7 +61,7 @@ object(C)#%d (2) { NULL } # Proxy -int(1) +int(2) bool(true) lazy proxy object(C)#%d (1) { ["instance"]=> @@ -59,3 +72,19 @@ lazy proxy object(C)#%d (1) { NULL } } +string(11) "initializer" +# Nested Proxy +int(2) +bool(true) +lazy proxy object(C)#%d (1) { + ["instance"]=> + lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(2) + ["b"]=> + NULL + } + } +} diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 36edb6b527e15..7d2c079440d04 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6205,6 +6205,11 @@ ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization) RETURN_THROWS(); } + while (zend_object_is_lazy_proxy(object) + && zend_lazy_object_initialized(object)) { + object = zend_lazy_object_get_instance(object); + } + zval *var_ptr = OBJ_PROP(object, ref->prop->offset); bool prop_was_lazy = Z_PROP_FLAG_P(var_ptr) & IS_PROP_LAZY; @@ -6248,12 +6253,16 @@ ZEND_METHOD(ReflectionProperty, skipLazyInitialization) RETURN_THROWS(); } - bool prop_was_lazy = (Z_PROP_FLAG_P(OBJ_PROP(object, ref->prop->offset)) & IS_PROP_LAZY); + while (zend_object_is_lazy_proxy(object) + && zend_lazy_object_initialized(object)) { + object = zend_lazy_object_get_instance(object); + } zval *src = &object->ce->default_properties_table[OBJ_PROP_TO_NUM(ref->prop->offset)]; zval *dst = OBJ_PROP(object, ref->prop->offset); + bool prop_was_lazy = (Z_PROP_FLAG_P(dst) & IS_PROP_LAZY); - if (!(Z_PROP_FLAG_P(dst) & IS_PROP_LAZY)) { + if (!prop_was_lazy) { /* skipLazyInitialization has no effect on non-lazy properties */ return; }