Skip to content

Commit 2ced1c9

Browse files
Add ReflectionProperty::isDynamic() as an alternative to isDefault() (#15758)
Dynamic properties are generally referred to as "dynamic" properties, while non-dynamic properties are not commonly referred to as "default" properties. Thus, the existing method `ReflectionProperty::isDefault()` has a non obvious name; while an alias could be added for `isNotDynamic()`, a new `isDynamic()` method seems cleaner. The new method returns the opposite of `isDefault()`; dynamic properties are not present on the class by default, and properties present by default are not added dynamically. Closes GH-15754
1 parent c9862ba commit 2ced1c9

File tree

6 files changed

+131
-8
lines changed

6 files changed

+131
-8
lines changed

UPGRADING

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ PHP 8.4 UPGRADE NOTES
431431
- ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE
432432
- ReflectionClass::SKIP_DESTRUCTOR
433433
RFC: https://wiki.php.net/rfc/lazy-objects
434+
. ReflectionProperty::isDynamic() was introduced.
434435

435436
- SOAP:
436437
. Added support for clark notation for namespaces in class map.

ext/reflection/php_reflection.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5921,8 +5921,7 @@ ZEND_METHOD(ReflectionProperty, isVirtual)
59215921
_property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_VIRTUAL);
59225922
}
59235923

5924-
/* {{{ Returns whether this property is default (declared at compilation time). */
5925-
ZEND_METHOD(ReflectionProperty, isDefault)
5924+
static void _property_check_dynamic(INTERNAL_FUNCTION_PARAMETERS, bool dynamic_true)
59265925
{
59275926
reflection_object *intern;
59285927
property_reference *ref;
@@ -5931,7 +5930,21 @@ ZEND_METHOD(ReflectionProperty, isDefault)
59315930
RETURN_THROWS();
59325931
}
59335932
GET_REFLECTION_OBJECT_PTR(ref);
5934-
RETURN_BOOL(ref->prop != NULL);
5933+
bool is_dynamic = ref->prop == NULL;
5934+
RETURN_BOOL(dynamic_true ? is_dynamic : !is_dynamic);
5935+
}
5936+
5937+
/* {{{ Returns whether this property is default (declared at compilation time). */
5938+
ZEND_METHOD(ReflectionProperty, isDefault)
5939+
{
5940+
_property_check_dynamic(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
5941+
}
5942+
/* }}} */
5943+
5944+
/* {{{ Returns whether this property is dynamic (not declared at compilation time). */
5945+
ZEND_METHOD(ReflectionProperty, isDynamic)
5946+
{
5947+
_property_check_dynamic(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
59355948
}
59365949
/* }}} */
59375950

ext/reflection/php_reflection.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,8 @@ public function isReadOnly(): bool {}
522522
/** @tentative-return-type */
523523
public function isDefault(): bool {}
524524

525+
public function isDynamic(): bool {}
526+
525527
public function isAbstract(): bool {}
526528

527529
public function isVirtual(): bool {}

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.

ext/reflection/tests/ReflectionProperty_basic2.phpt

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
--TEST--
2-
Test usage of ReflectionProperty methods isDefault(), getModifiers(), getDeclaringClass() and getDocComment().
2+
Test usage of ReflectionProperty methods isDefault(), isDynamic(), getModifiers(), getDeclaringClass() and getDocComment().
33
--INI--
44
opcache.save_comments=1
55
--FILE--
66
<?php
77

8-
function reflectProperty($class, $property) {
9-
$propInfo = new ReflectionProperty($class, $property);
8+
function reflectProperty($classOrObj, $property, $className = null) {
9+
$className ??= $classOrObj;
10+
$propInfo = new ReflectionProperty($classOrObj, $property);
1011
echo "**********************************\n";
11-
echo "Reflecting on property $class::$property\n\n";
12+
echo "Reflecting on property $className::$property\n\n";
1213
echo "isDefault():\n";
1314
var_dump($propInfo->isDefault());
15+
echo "isDynamic():\n";
16+
var_dump($propInfo->isDynamic());
1417
echo "getModifiers():\n";
1518
var_dump($propInfo->getModifiers());
1619
echo "getDeclaringClass():\n";
@@ -20,6 +23,7 @@ function reflectProperty($class, $property) {
2023
echo "\n**********************************\n";
2124
}
2225

26+
#[AllowDynamicProperties]
2327
class TestClass {
2428
public $pub;
2529
static public $stat = "static property";
@@ -35,13 +39,19 @@ reflectProperty("TestClass", "stat");
3539
reflectProperty("TestClass", "prot");
3640
reflectProperty("TestClass", "priv");
3741

42+
$obj = new TestClass();
43+
$obj->dyn = 'dynamic';
44+
reflectProperty($obj, "dyn", "TestClass");
45+
3846
?>
3947
--EXPECTF--
4048
**********************************
4149
Reflecting on property TestClass::pub
4250

4351
isDefault():
4452
bool(true)
53+
isDynamic():
54+
bool(false)
4555
getModifiers():
4656
int(1)
4757
getDeclaringClass():
@@ -58,6 +68,8 @@ Reflecting on property TestClass::stat
5868

5969
isDefault():
6070
bool(true)
71+
isDynamic():
72+
bool(false)
6173
getModifiers():
6274
int(17)
6375
getDeclaringClass():
@@ -74,6 +86,8 @@ Reflecting on property TestClass::prot
7486

7587
isDefault():
7688
bool(true)
89+
isDynamic():
90+
bool(false)
7791
getModifiers():
7892
int(2)
7993
getDeclaringClass():
@@ -92,6 +106,8 @@ Reflecting on property TestClass::priv
92106

93107
isDefault():
94108
bool(true)
109+
isDynamic():
110+
bool(false)
95111
getModifiers():
96112
int(4)
97113
getDeclaringClass():
@@ -103,3 +119,21 @@ getDocComment():
103119
bool(false)
104120

105121
**********************************
122+
**********************************
123+
Reflecting on property TestClass::dyn
124+
125+
isDefault():
126+
bool(false)
127+
isDynamic():
128+
bool(true)
129+
getModifiers():
130+
int(1)
131+
getDeclaringClass():
132+
object(ReflectionClass)#%d (1) {
133+
["name"]=>
134+
string(9) "TestClass"
135+
}
136+
getDocComment():
137+
bool(false)
138+
139+
**********************************
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
--TEST--
2+
Test ReflectionProperty::isDynamic() usage.
3+
--FILE--
4+
<?php
5+
6+
function reflectProperty($classOrObj, $property, $className = null) {
7+
$className ??= $classOrObj;
8+
$propInfo = new ReflectionProperty($classOrObj, $property);
9+
echo "**********************************\n";
10+
echo "Reflecting on property $className::$property\n\n";
11+
echo "isDynamic():\n";
12+
var_dump($propInfo->isDynamic());
13+
echo "\n**********************************\n";
14+
}
15+
16+
#[AllowDynamicProperties]
17+
class TestClass {
18+
public $pub;
19+
static public $stat = "static property";
20+
protected $prot = 4;
21+
private $priv = "keepOut";
22+
}
23+
24+
reflectProperty("TestClass", "pub");
25+
reflectProperty("TestClass", "stat");
26+
reflectProperty("TestClass", "prot");
27+
reflectProperty("TestClass", "priv");
28+
29+
$obj = new TestClass();
30+
$obj->dyn = 'dynamic';
31+
reflectProperty($obj, "dyn", "TestClass");
32+
33+
?>
34+
--EXPECT--
35+
**********************************
36+
Reflecting on property TestClass::pub
37+
38+
isDynamic():
39+
bool(false)
40+
41+
**********************************
42+
**********************************
43+
Reflecting on property TestClass::stat
44+
45+
isDynamic():
46+
bool(false)
47+
48+
**********************************
49+
**********************************
50+
Reflecting on property TestClass::prot
51+
52+
isDynamic():
53+
bool(false)
54+
55+
**********************************
56+
**********************************
57+
Reflecting on property TestClass::priv
58+
59+
isDynamic():
60+
bool(false)
61+
62+
**********************************
63+
**********************************
64+
Reflecting on property TestClass::dyn
65+
66+
isDynamic():
67+
bool(true)
68+
69+
**********************************

0 commit comments

Comments
 (0)