Skip to content

Commit 1503720

Browse files
committed
ReflectionProperty::isInitialized() should not trigger lazy object initialization
1 parent cb63e4f commit 1503720

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

ext/reflection/php_reflection.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6289,6 +6289,22 @@ ZEND_METHOD(ReflectionProperty, isInitialized)
62896289
}
62906290
}
62916291

6292+
/* If this is an uninitialized lazy object, do not trigger initialization. */
6293+
if (ref->prop
6294+
&& !(prop_get_flags(ref) & ZEND_ACC_STATIC)
6295+
&& !(prop_get_flags(ref) & ZEND_ACC_VIRTUAL)
6296+
&& zend_object_is_lazy(Z_OBJ_P(object))
6297+
&& !zend_lazy_object_initialized(Z_OBJ_P(object))
6298+
) {
6299+
zval *slot = OBJ_PROP(Z_OBJ_P(object), ref->prop->offset);
6300+
6301+
if (Z_PROP_FLAG_P(slot) & IS_PROP_LAZY) {
6302+
RETURN_FALSE;
6303+
}
6304+
6305+
RETURN_BOOL(!Z_ISUNDEF_P(slot));
6306+
}
6307+
62926308
const zend_class_entry *old_scope = EG(fake_scope);
62936309
EG(fake_scope) = intern->ce;
62946310
retval = Z_OBJ_HT_P(object)->has_property(Z_OBJ_P(object),

ext/reflection/tests/gh20830.phpt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
--TEST--
2+
GH-20830: ReflectionProperty::isInitialized() should not trigger lazy object initialization
3+
--FILE--
4+
<?php
5+
6+
class TestClass {
7+
public readonly int $id;
8+
public string $name;
9+
}
10+
11+
$rc = new ReflectionClass(TestClass::class);
12+
13+
$obj = $rc->newLazyGhost(function ($ghost) {
14+
$rp = new ReflectionProperty(TestClass::class, 'id');
15+
$rp->setRawValueWithoutLazyInitialization($ghost, 123);
16+
$ghost->name = 'initialized';
17+
echo 'Ghost initialized' . PHP_EOL;
18+
});
19+
20+
echo 'Created lazy ghost' . PHP_EOL;
21+
var_dump($rc->isUninitializedLazyObject($obj));
22+
23+
echo 'Checking if $id is initialized...' . PHP_EOL;
24+
$rp = new ReflectionProperty(TestClass::class, 'id');
25+
var_dump($rp->isInitialized($obj));
26+
var_dump($rc->isUninitializedLazyObject($obj));
27+
28+
echo 'Accessing $id value...' . PHP_EOL;
29+
$rp->getValue($obj);
30+
var_dump($rp->isInitialized($obj));
31+
var_dump($rc->isUninitializedLazyObject($obj));
32+
?>
33+
--EXPECT--
34+
Created lazy ghost
35+
bool(true)
36+
Checking if $id is initialized...
37+
bool(false)
38+
bool(true)
39+
Accessing $id value...
40+
Ghost initialized
41+
bool(true)
42+
bool(false)

0 commit comments

Comments
 (0)