Commit d3f4eada100 for php.net
commit d3f4eada1001627df6330e7606081e7ab42ca311
Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>
Date: Tue Aug 11 15:15:37 2026 -0700
[RFC] Deprecate `ReflectionMethod` invocation for static methods with objects
`ReflectionMethod::invoke()` and `::invokeArgs()` are affected, but share
implementation code and so are updated together.
https://wiki.php.net/rfc/deprecations_php_8_6
diff --git a/UPGRADING b/UPGRADING
index bfc23acb0fa..a4cc44f9a00 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -483,6 +483,9 @@ PHP 8.6 UPGRADE NOTES
. Calling ReflectionProperty::setRawValue() with an object that is not an
instance of the class on which the property was declared is now deprecated.
RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_reflectionpropertysetvalue_and_reflectionpropertysetrawvalue_with_wrong_types
+ . Calling ReflectionMethod::invoke() or ReflectionMethod::invokeArgs() with
+ an object and a static method is now deprecated.
+ RFC: https://wiki.php.net/rfc/deprecations_php_8_6#deprecate_reflectionmethodinvoke_and_reflectionmethodinvokeargs_with_objects_for_static_methods
- SPL:
. The spl_classes() function is now deprecated, use
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 426ac625a9f..07a671739f3 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -3375,7 +3375,21 @@ static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, bool variadic
* Else, we verify that the given object is an instance of the class.
*/
if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
- object = NULL;
+ if (object) {
+ zend_string *method_name = get_active_function_or_method_name();
+ zend_error(
+ E_DEPRECATED,
+ "Calling %pS() for static method %pS::%pS() does not need an object parameter",
+ method_name,
+ mptr->common.scope->name,
+ mptr->common.function_name
+ );
+ zend_string_release(method_name);
+ if (UNEXPECTED(EG(exception))) {
+ RETURN_THROWS();
+ }
+ object = NULL;
+ }
obj_ce = mptr->common.scope;
} else {
if (!object) {
diff --git a/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt b/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt
index 124f728052e..57f4702e07c 100644
--- a/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt
+++ b/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt
@@ -65,7 +65,7 @@ abstract function foo();
}
?>
---EXPECT--
+--EXPECTF--
Non-instance:
string(72) "Given object is not an instance of the class this method was declared in"
@@ -75,6 +75,8 @@ abstract function foo();
NULL
Private method:
+
+Deprecated: Calling ReflectionMethod::invokeArgs() for static method TestClass::privateMethod() does not need an object parameter in %s on line %d
Called privateMethod()
NULL
diff --git a/ext/reflection/tests/ReflectionMethod_invoke_basic.phpt b/ext/reflection/tests/ReflectionMethod_invoke_basic.phpt
index 66f3c50da02..2d35451fa94 100644
--- a/ext/reflection/tests/ReflectionMethod_invoke_basic.phpt
+++ b/ext/reflection/tests/ReflectionMethod_invoke_basic.phpt
@@ -104,6 +104,8 @@ abstract function foo();
Static method:
ReflectionMethod::invoke() expects at least 1 argument, 0 given
ReflectionMethod::invoke(): Argument #1 ($object) must be of type ?object, true given
+
+Deprecated: Calling ReflectionMethod::invoke() for static method TestClass::staticMethod() does not need an object parameter in %s on line %d
Called staticMethod()
Exception: Using $this when not in object context
NULL
diff --git a/ext/reflection/tests/ReflectionMethod_invoke_error1.phpt b/ext/reflection/tests/ReflectionMethod_invoke_error1.phpt
index 1ddf1c51c13..dd86baa9104 100644
--- a/ext/reflection/tests/ReflectionMethod_invoke_error1.phpt
+++ b/ext/reflection/tests/ReflectionMethod_invoke_error1.phpt
@@ -53,7 +53,7 @@ abstract function foo();
}
?>
---EXPECT--
+--EXPECTF--
invoke() on a non-object:
string(85) "ReflectionMethod::invoke(): Argument #1 ($object) must be of type ?object, true given"
@@ -61,6 +61,8 @@ abstract function foo();
string(72) "Given object is not an instance of the class this method was declared in"
Private method:
+
+Deprecated: Calling ReflectionMethod::invoke() for static method TestClass::privateMethod() does not need an object parameter in %s on line %d
Called privateMethod()
NULL