Always use __invoke callable name for objects

The callable name is provided also if it's not callable, in which
case it's basically "what it would be if it were callable", which
is ClassName::__invoke. The current behavior of casting the object
to string makes very little sense as this will just throw an
exception for most objects.
This commit is contained in:
Nikita Popov 2020-04-14 17:02:47 +02:00
parent bac5137e4e
commit 4a935bc2c9
2 changed files with 70 additions and 15 deletions

View File

@ -3136,21 +3136,12 @@ try_again:
}
case IS_OBJECT:
{
zend_class_entry *calling_scope;
zend_function *fptr;
zend_object *object;
zend_object *zobj = Z_OBJ_P(callable);
if (zobj->handlers->get_closure
&& zobj->handlers->get_closure(zobj, &calling_scope, &fptr, &object, 1) == SUCCESS) {
zend_class_entry *ce = zobj->ce;
zend_string *callable_name = zend_string_alloc(
ZSTR_LEN(ce->name) + sizeof("::__invoke") - 1, 0);
memcpy(ZSTR_VAL(callable_name), ZSTR_VAL(ce->name), ZSTR_LEN(ce->name));
memcpy(ZSTR_VAL(callable_name) + ZSTR_LEN(ce->name), "::__invoke", sizeof("::__invoke"));
return callable_name;
}
return zval_get_string_func(callable);
zend_class_entry *ce = Z_OBJCE_P(callable);
zend_string *callable_name = zend_string_alloc(
ZSTR_LEN(ce->name) + sizeof("::__invoke") - 1, 0);
memcpy(ZSTR_VAL(callable_name), ZSTR_VAL(ce->name), ZSTR_LEN(ce->name));
memcpy(ZSTR_VAL(callable_name) + ZSTR_LEN(ce->name), "::__invoke", sizeof("::__invoke"));
return callable_name;
}
case IS_REFERENCE:
callable = Z_REFVAL_P(callable);

View File

@ -116,6 +116,7 @@ foreach($objects as $object) {
array( @$temp_class_obj->value, 100 ),
array( $object, 'func' ),
array( 'object_class', 'foo1' ),
$object,
);
/* use check_iscallable_objects() to check whether given object/string
has valid method name */
@ -213,6 +214,14 @@ bool(true)
object_class::foo1
bool(false)
object_class::foo1
-- Innerloop iteration 11 of Outerloop iteration 1 --
bool(false)
bool(false)
bool(false)
bool(false)
object_class::__invoke
bool(false)
object_class::__invoke
--- Outerloop iteration 2 ---
-- Innerloop iteration 1 of Outerloop iteration 2 --
bool(false)
@ -294,6 +303,14 @@ bool(true)
object_class::foo1
bool(false)
object_class::foo1
-- Innerloop iteration 11 of Outerloop iteration 2 --
bool(false)
bool(false)
bool(false)
bool(false)
no_member_class::__invoke
bool(false)
no_member_class::__invoke
--- Outerloop iteration 3 ---
-- Innerloop iteration 1 of Outerloop iteration 3 --
bool(false)
@ -375,6 +392,14 @@ bool(true)
object_class::foo1
bool(false)
object_class::foo1
-- Innerloop iteration 11 of Outerloop iteration 3 --
bool(false)
bool(false)
bool(false)
bool(false)
contains_object_class::__invoke
bool(false)
contains_object_class::__invoke
--- Outerloop iteration 4 ---
-- Innerloop iteration 1 of Outerloop iteration 4 --
bool(false)
@ -456,6 +481,14 @@ bool(true)
object_class::foo1
bool(false)
object_class::foo1
-- Innerloop iteration 11 of Outerloop iteration 4 --
bool(false)
bool(false)
bool(false)
bool(false)
contains_object_class::__invoke
bool(false)
contains_object_class::__invoke
--- Outerloop iteration 5 ---
-- Innerloop iteration 1 of Outerloop iteration 5 --
bool(true)
@ -537,6 +570,14 @@ bool(true)
object_class::foo1
bool(false)
object_class::foo1
-- Innerloop iteration 11 of Outerloop iteration 5 --
bool(false)
bool(false)
bool(false)
bool(false)
object_class::__invoke
bool(false)
object_class::__invoke
--- Outerloop iteration 6 ---
-- Innerloop iteration 1 of Outerloop iteration 6 --
bool(false)
@ -618,6 +659,14 @@ bool(true)
object_class::foo1
bool(false)
object_class::foo1
-- Innerloop iteration 11 of Outerloop iteration 6 --
bool(false)
bool(false)
bool(false)
bool(false)
no_member_class::__invoke
bool(false)
no_member_class::__invoke
--- Outerloop iteration 7 ---
-- Innerloop iteration 1 of Outerloop iteration 7 --
bool(true)
@ -699,6 +748,14 @@ bool(true)
object_class::foo1
bool(false)
object_class::foo1
-- Innerloop iteration 11 of Outerloop iteration 7 --
bool(false)
bool(false)
bool(false)
bool(false)
object_class::__invoke
bool(false)
object_class::__invoke
--- Outerloop iteration 8 ---
-- Innerloop iteration 1 of Outerloop iteration 8 --
bool(false)
@ -780,3 +837,10 @@ bool(true)
object_class::foo1
bool(false)
object_class::foo1
-- Innerloop iteration 11 of Outerloop iteration 8 --
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)