1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

zend_get_callable_name: Return underlying callable’s name for fake closures (#18063)

Fixes php/php-src#18062
This commit is contained in:
Tim Düsterhus
2025-03-17 13:55:24 +01:00
committed by GitHub
parent 81ef122ca9
commit 6962540662
4 changed files with 49 additions and 0 deletions

2
NEWS
View File

@@ -169,6 +169,8 @@ PHP NEWS
- Standard:
. Fixed crypt() tests on musl when using --with-external-libcrypt
(Michael Orlitzky).
. Fixed bug GH-18062 (is_callable(func(...), callable_name: $name) for first
class callables returns wrong name). (timwolla)
- Streams:
. Fixed bug GH-16889 (stream_select() timeout useless for pipes on Windows).

View File

@@ -19,6 +19,8 @@ PHP 8.5 INTERNALS UPGRADE NOTES
a value to a non-reference zval.
. Added zval_ptr_safe_dtor() to safely destroy a zval when a destructor
could interfere.
. zend_get_callable_name() now returns the name of the underlying function
for fake closures.
========================
2. Build system changes

View File

@@ -0,0 +1,32 @@
--TEST--
First Class Callable returns correct name from is_callable()
--FILE--
<?php
class Foo {
public function __invoke() {
}
public static function bar() {
}
}
function some_func() {
}
is_callable(some_func(...), callable_name: $name);
var_dump($name);
is_callable((new Foo())(...), callable_name: $name);
var_dump($name);
is_callable(Foo::bar(...), callable_name: $name);
var_dump($name);
?>
--EXPECT--
string(9) "some_func"
string(13) "Foo::__invoke"
string(8) "Foo::bar"

View File

@@ -4134,6 +4134,19 @@ try_again:
case IS_OBJECT:
{
zend_class_entry *ce = Z_OBJCE_P(callable);
if (ce == zend_ce_closure) {
const zend_function *fn = zend_get_closure_method_def(Z_OBJ_P(callable));
if (fn->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
if (fn->common.scope) {
return zend_create_member_string(fn->common.scope->name, fn->common.function_name);
} else {
return zend_string_copy(fn->common.function_name);
}
}
}
return zend_string_concat2(
ZSTR_VAL(ce->name), ZSTR_LEN(ce->name),
"::__invoke", sizeof("::__invoke") - 1);