Skip to content

Commit 50a3f01

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: Add ReflectionProperty::isLazy()
2 parents ee19427 + 54a40f3 commit 50a3f01

File tree

4 files changed

+171
-1
lines changed

4 files changed

+171
-1
lines changed

Zend/tests/lazy_objects/isLazy.phpt

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
--TEST--
2+
Lazy Objects: ReflectionProperty::isLazy()
3+
--FILE--
4+
<?php
5+
6+
#[AllowDynamicProperties]
7+
class C {
8+
public static $staticProp;
9+
public int $typed;
10+
public $untyped;
11+
public $virtual {
12+
get {}
13+
}
14+
}
15+
16+
function testProps(ReflectionClass $reflector, object $obj) {
17+
foreach (['staticProp', 'typed', 'untyped', 'virtual', 'dynamic'] as $name) {
18+
if ('dynamic' === $name) {
19+
$tmp = new C();
20+
$tmp->dynamic = 1;
21+
$pr = new ReflectionProperty($tmp, $name);
22+
} else {
23+
$pr = $reflector->getProperty($name);
24+
}
25+
printf("%s: %d\n", $name, $pr->isLazy($obj));
26+
}
27+
}
28+
29+
$reflector = new ReflectionClass(C::class);
30+
31+
print "# Ghost\n";
32+
33+
$obj = $reflector->newLazyGhost(function () { });
34+
35+
testProps($reflector, $obj);
36+
37+
$pr = $reflector->getProperty('typed');
38+
$pr->skipLazyInitialization($obj);
39+
printf("typed (skipped): %d\n", $pr->isLazy($obj));
40+
41+
print "# Initialized Ghost\n";
42+
43+
$reflector->initializeLazyObject($obj);
44+
45+
testProps($reflector, $obj);
46+
47+
print "# Proxy\n";
48+
49+
$obj = $reflector->newLazyProxy(function () {
50+
return new C();
51+
});
52+
53+
testProps($reflector, $obj);
54+
55+
$pr = $reflector->getProperty('typed');
56+
$pr->skipLazyInitialization($obj);
57+
printf("typed (skipped prop): %d\n", $pr->isLazy($obj));
58+
59+
print "# Initialized Proxy\n";
60+
61+
$reflector->initializeLazyObject($obj);
62+
63+
testProps($reflector, $obj);
64+
65+
print "# Nested Proxy\n";
66+
67+
$nested = new C();
68+
$obj = $reflector->newLazyProxy(function () use ($nested) {
69+
return $nested;
70+
});
71+
$reflector->initializeLazyObject($obj);
72+
$reflector->resetAsLazyProxy($nested, function () {
73+
return new C();
74+
});
75+
76+
testProps($reflector, $obj);
77+
78+
print "# Nested Proxy (nested initialized)\n";
79+
80+
$nested = new C();
81+
$obj = $reflector->newLazyProxy(function () use ($nested) {
82+
return $nested;
83+
});
84+
$reflector->initializeLazyObject($obj);
85+
$reflector->resetAsLazyProxy($nested, function () {
86+
return new C();
87+
});
88+
$reflector->initializeLazyObject($nested);
89+
90+
testProps($reflector, $obj);
91+
92+
print "# Internal\n";
93+
94+
$obj = (new DateTime())->diff(new DateTime());
95+
$reflector = new ReflectionClass(DateInterval::class);
96+
$pr = new ReflectionProperty($obj, 'y');
97+
printf("y: %d\n", $pr->isLazy($obj));
98+
99+
?>
100+
--EXPECT--
101+
# Ghost
102+
staticProp: 0
103+
typed: 1
104+
untyped: 1
105+
virtual: 0
106+
dynamic: 0
107+
typed (skipped): 0
108+
# Initialized Ghost
109+
staticProp: 0
110+
typed: 0
111+
untyped: 0
112+
virtual: 0
113+
dynamic: 0
114+
# Proxy
115+
staticProp: 0
116+
typed: 1
117+
untyped: 1
118+
virtual: 0
119+
dynamic: 0
120+
typed (skipped prop): 0
121+
# Initialized Proxy
122+
staticProp: 0
123+
typed: 0
124+
untyped: 0
125+
virtual: 0
126+
dynamic: 0
127+
# Nested Proxy
128+
staticProp: 0
129+
typed: 1
130+
untyped: 1
131+
virtual: 0
132+
dynamic: 0
133+
# Nested Proxy (nested initialized)
134+
staticProp: 0
135+
typed: 0
136+
untyped: 0
137+
virtual: 0
138+
dynamic: 0
139+
# Internal
140+
y: 0

ext/reflection/php_reflection.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6049,6 +6049,30 @@ ZEND_METHOD(ReflectionProperty, skipLazyInitialization)
60496049
}
60506050
}
60516051

6052+
ZEND_METHOD(ReflectionProperty, isLazy)
6053+
{
6054+
reflection_object *intern;
6055+
property_reference *ref;
6056+
zend_object *object;
6057+
6058+
GET_REFLECTION_OBJECT_PTR(ref);
6059+
6060+
ZEND_PARSE_PARAMETERS_START(1, 1) {
6061+
Z_PARAM_OBJ_OF_CLASS(object, intern->ce)
6062+
} ZEND_PARSE_PARAMETERS_END();
6063+
6064+
if (!ref->prop || ref->prop->flags & (ZEND_ACC_STATIC | ZEND_ACC_VIRTUAL)) {
6065+
RETURN_FALSE;
6066+
}
6067+
6068+
while (zend_object_is_lazy_proxy(object)
6069+
&& zend_lazy_object_initialized(object)) {
6070+
object = zend_lazy_object_get_instance(object);
6071+
}
6072+
6073+
RETURN_BOOL(Z_PROP_FLAG_P(OBJ_PROP(object, ref->prop->offset)) & IS_PROP_LAZY);
6074+
}
6075+
60526076
/* {{{ Returns true if property was initialized */
60536077
ZEND_METHOD(ReflectionProperty, isInitialized)
60546078
{

ext/reflection/php_reflection.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,8 @@ public function setRawValueWithoutLazyInitialization(object $object, mixed $valu
496496

497497
public function skipLazyInitialization(object $object): void {}
498498

499+
public function isLazy(object $object): bool {}
500+
499501
/** @tentative-return-type */
500502
public function isInitialized(?object $object = null): bool {}
501503

ext/reflection/php_reflection_arginfo.h

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)