diff --git a/NEWS b/NEWS index f81abcaad6da..33065772c0e3 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,8 @@ PHP NEWS . Fixed skipped catch block when switching fibers during exception unwinding (Nicolas Grekas) . Fix escape analysis for objects implementing ArrayAccess. (ndossche, Arnaud) + . Fixed array_map() optimization not resolving the class name of a static + first-class callable. (Claudio Dekker) - Fileinfo: . Fixed bug GH-24289 (finfo::file() reports the wrong argument number for diff --git a/Zend/tests/array_map_foreach_optimization_class_name.phpt b/Zend/tests/array_map_foreach_optimization_class_name.phpt new file mode 100644 index 000000000000..fab9c51ee552 --- /dev/null +++ b/Zend/tests/array_map_foreach_optimization_class_name.phpt @@ -0,0 +1,74 @@ +--TEST-- +array_map(): foreach optimization resolves the class name of a static FCC +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + int(2) +} +array(1) { + [0]=> + int(3) +} +array(1) { + [0]=> + int(3) +} +array(1) { + [0]=> + int(3) +} +array(1) { + [0]=> + int(2) +} +array(1) { + [0]=> + int(2) +} +array(1) { + [0]=> + int(2) +} +array(1) { + [0]=> + int(2) +} diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index fe8f978ff59c..40f90e384754 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5375,7 +5375,15 @@ static zend_result zend_compile_func_array_map(znode *result, zend_ast_list *arg /* Evaluate class name */ znode class_node; - if (callback->kind == ZEND_AST_STATIC_CALL) { + if (callback->kind == ZEND_AST_STATIC_CALL + && callback->child[0]->kind == ZEND_AST_ZVAL + && Z_TYPE_P(zend_ast_get_zval(callback->child[0])) == IS_STRING + && zend_get_class_fetch_type(zend_ast_get_str(callback->child[0])) == ZEND_FETCH_CLASS_DEFAULT) { + /* Resolve the name against the namespace and imports, as compiling it + * as an expression would yield the unresolved string. */ + class_node.op_type = IS_CONST; + ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(callback->child[0])); + } else if (callback->kind == ZEND_AST_STATIC_CALL) { znode result; zend_compile_expr(&result, callback->child[0]); if (result.op_type == IS_CONST || result.op_type == IS_TMP_VAR) {