Commit 08c039c87a0 for php.net
commit 08c039c87a06eccf110076960e15a3ec71851953
Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>
Date: Thu Jul 2 13:46:16 2026 -0700
`ReflectionClass::getStaticProperties()`: optimize array initialization
For classes with no static properties, avoid allocating an array that will be
empty. Includes a regression test for the function since it was previously
untested, to confirm that even when a class declares no static properties of
its own, inherited static properties are still returned.
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 69ce3ae8a93..3abd95731ca 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -4159,7 +4159,17 @@ ZEND_METHOD(ReflectionClass, getStaticProperties)
RETURN_THROWS();
}
- if (ce->default_static_members_count && !CE_STATIC_MEMBERS(ce)) {
+ // default_static_members_count includes inherited static members, see
+ // zend_do_inheritance_ex().
+ // PHP does not support *dynamic* static properties the same way non-static
+ // properties can be dynamic (i.e. present on an object without having been
+ // declared on the class). Thus, default_static_members_count will always
+ // reflect the count of all static members that a class might have.
+ if (ce->default_static_members_count == 0) {
+ RETURN_EMPTY_ARRAY();
+ }
+
+ if (!CE_STATIC_MEMBERS(ce)) {
zend_class_init_statics(ce);
}
diff --git a/ext/reflection/tests/ReflectionClass_getStaticProperties.phpt b/ext/reflection/tests/ReflectionClass_getStaticProperties.phpt
new file mode 100644
index 00000000000..89d894f8398
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_getStaticProperties.phpt
@@ -0,0 +1,57 @@
+--TEST--
+ReflectionClass::getStaticProperties()
+--FILE--
+<?php
+class Base {
+ public static $pub;
+ private static $priv;
+ public static mixed $pubTyped;
+ private static mixed $privTyped;
+}
+
+class Child extends Base {}
+
+$base = new ReflectionClass(Base::class);
+$child = new ReflectionClass(Child::class);
+
+echo "Start:\n";
+var_dump($base->getStaticProperties());
+var_dump($child->getStaticProperties());
+
+echo "\nTyped properties initialized\n:";
+Base::$pubTyped = true;
+$base->setStaticPropertyValue('privTyped', true);
+
+var_dump($base->getStaticProperties());
+var_dump($child->getStaticProperties());
+?>
+--EXPECT--
+Start:
+array(2) {
+ ["pub"]=>
+ NULL
+ ["priv"]=>
+ NULL
+}
+array(1) {
+ ["pub"]=>
+ NULL
+}
+
+Typed properties initialized
+:array(4) {
+ ["pub"]=>
+ NULL
+ ["priv"]=>
+ NULL
+ ["pubTyped"]=>
+ bool(true)
+ ["privTyped"]=>
+ bool(true)
+}
+array(2) {
+ ["pub"]=>
+ NULL
+ ["pubTyped"]=>
+ bool(true)
+}