Commit 0dc8a54f629 for php.net

commit 0dc8a54f6296bd6738571ef116c23143724611cf
Author: Gina Peter Banyard <girgias@php.net>
Date:   Thu Jul 30 22:21:32 2026 +0100

    Zend: move true function search out of main callability check

    And rename C function to zend_is_method_callable

diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 83c1ed312c7..299d5d57a24 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -3818,7 +3818,7 @@ ZEND_API void zend_release_fcall_info_cache(zend_fcall_info_cache *fcc) {
 	}
 }

-static zend_always_inline bool zend_is_string_callable(zend_string *callable, const zend_execute_data *frame, zend_fcall_info_cache *fcc, bool strict_class, char **error, bool suppress_deprecation) /* {{{ */
+static zend_always_inline bool zend_is_method_callable(zend_string *callable, const zend_execute_data *frame, zend_fcall_info_cache *fcc, bool strict_class, char **error, bool suppress_deprecation) /* {{{ */
 {
 	zend_class_entry *ce_org = fcc->calling_scope;
 	bool retval = false;
@@ -3831,14 +3831,6 @@ static zend_always_inline bool zend_is_string_callable(zend_string *callable, co

 	fcc->calling_scope = NULL;

-	if (!ce_org) {
-		zend_function *func = zend_fetch_function(callable);
-		if (EXPECTED(func != NULL)) {
-			fcc->function_handler = func;
-			return 1;
-		}
-	}
-
 	/* Split name into class/namespace and method/function names */
 	if ((colon = zend_memrchr(ZSTR_VAL(callable), ':', ZSTR_LEN(callable))) != NULL &&
 		colon > ZSTR_VAL(callable) &&
@@ -4176,17 +4168,29 @@ ZEND_API bool zend_is_callable_at_frame(
 again:
 	switch (Z_TYPE_P(callable)) {
 		case IS_STRING:
-			if (object) {
+			/* First check for a normal function */
+			if (!object) {
+				if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
+					return true;
+				}
+
+				zend_function *func = zend_fetch_function(Z_STR_P(callable));
+				if (EXPECTED(func != NULL)) {
+					fcc->function_handler = func;
+					return true;
+				}
+				/* Might be a static method */
+			} else {
 				fcc->object = object;
 				fcc->calling_scope = object->ce;
 			}

 			if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
 				fcc->called_scope = fcc->calling_scope;
-				return 1;
+				return true;
 			}

-			ret = zend_is_string_callable(Z_STR_P(callable), frame, fcc, strict_class, error, check_flags & IS_CALLABLE_SUPPRESS_DEPRECATIONS);
+			ret = zend_is_method_callable(Z_STR_P(callable), frame, fcc, strict_class, error, check_flags & IS_CALLABLE_SUPPRESS_DEPRECATIONS);
 			break;

 		case IS_ARRAY:
@@ -4234,7 +4238,7 @@ ZEND_API bool zend_is_callable_at_frame(
 					}
 				}

-				ret = zend_is_string_callable(Z_STR_P(method), frame, fcc, strict_class, error, check_flags & IS_CALLABLE_SUPPRESS_DEPRECATIONS);
+				ret = zend_is_method_callable(Z_STR_P(method), frame, fcc, strict_class, error, check_flags & IS_CALLABLE_SUPPRESS_DEPRECATIONS);
 				break;
 			}