Commit 8ddd6e38d2b for php.net
commit 8ddd6e38d2bad972ac95a39d0a3ece521a37ca14
Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>
Date: Wed Jul 8 19:45:33 2026 -0700
Reflection: optimize closure checking
Optimize
- `ReflectionParameter::__construct()`
- `ReflectionClass::getMethods()`
Given that the `Closure` class is declared as `final`, for some class entry
`ce` to represent an instance of a `Closure` it must be exactly
`zend_ce_closure`. Replace the `instanceof_function()` call with a simple
pointer comparison.
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 89e41a2d11a..f8fef641f6f 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -2574,7 +2574,8 @@ ZEND_METHOD(ReflectionParameter, __construct)
case IS_OBJECT: {
ce = Z_OBJCE_P(reference);
- if (instanceof_function(ce, zend_ce_closure)) {
+ // No need for instanceof_function, the Closure class is final
+ if (ce == zend_ce_closure) {
fptr = (zend_function *)zend_get_closure_method_def(Z_OBJ_P(reference));
Z_ADDREF_P(reference);
is_closure = true;
@@ -4585,7 +4586,8 @@ ZEND_METHOD(ReflectionClass, getMethods)
_addmethod(mptr, ce, Z_ARRVAL_P(return_value), filter);
} ZEND_HASH_FOREACH_END();
- if (instanceof_function(ce, zend_ce_closure)) {
+ // No need for instanceof_function, the Closure class is final
+ if (ce == zend_ce_closure) {
bool has_obj = Z_TYPE(intern->obj) != IS_UNDEF;
zval obj_tmp;
zend_object *obj;