Skip to content

Commit 4a935bc

Browse files
committed
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.
1 parent bac5137 commit 4a935bc

File tree

2 files changed

+70
-15
lines changed

2 files changed

+70
-15
lines changed

Zend/zend_API.c

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3136,21 +3136,12 @@ ZEND_API zend_string *zend_get_callable_name_ex(zval *callable, zend_object *obj
31363136
}
31373137
case IS_OBJECT:
31383138
{
3139-
zend_class_entry *calling_scope;
3140-
zend_function *fptr;
3141-
zend_object *object;
3142-
zend_object *zobj = Z_OBJ_P(callable);
3143-
3144-
if (zobj->handlers->get_closure
3145-
&& zobj->handlers->get_closure(zobj, &calling_scope, &fptr, &object, 1) == SUCCESS) {
3146-
zend_class_entry *ce = zobj->ce;
3147-
zend_string *callable_name = zend_string_alloc(
3148-
ZSTR_LEN(ce->name) + sizeof("::__invoke") - 1, 0);
3149-
memcpy(ZSTR_VAL(callable_name), ZSTR_VAL(ce->name), ZSTR_LEN(ce->name));
3150-
memcpy(ZSTR_VAL(callable_name) + ZSTR_LEN(ce->name), "::__invoke", sizeof("::__invoke"));
3151-
return callable_name;
3152-
}
3153-
return zval_get_string_func(callable);
3139+
zend_class_entry *ce = Z_OBJCE_P(callable);
3140+
zend_string *callable_name = zend_string_alloc(
3141+
ZSTR_LEN(ce->name) + sizeof("::__invoke") - 1, 0);
3142+
memcpy(ZSTR_VAL(callable_name), ZSTR_VAL(ce->name), ZSTR_LEN(ce->name));
3143+
memcpy(ZSTR_VAL(callable_name) + ZSTR_LEN(ce->name), "::__invoke", sizeof("::__invoke"));
3144+
return callable_name;
31543145
}
31553146
case IS_REFERENCE:
31563147
callable = Z_REFVAL_P(callable);

ext/standard/tests/general_functions/is_callable_basic2.phpt

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ foreach($objects as $object) {
116116
array( @$temp_class_obj->value, 100 ),
117117
array( $object, 'func' ),
118118
array( 'object_class', 'foo1' ),
119+
$object,
119120
);
120121
/* use check_iscallable_objects() to check whether given object/string
121122
has valid method name */
@@ -213,6 +214,14 @@ bool(true)
213214
object_class::foo1
214215
bool(false)
215216
object_class::foo1
217+
-- Innerloop iteration 11 of Outerloop iteration 1 --
218+
bool(false)
219+
bool(false)
220+
bool(false)
221+
bool(false)
222+
object_class::__invoke
223+
bool(false)
224+
object_class::__invoke
216225
--- Outerloop iteration 2 ---
217226
-- Innerloop iteration 1 of Outerloop iteration 2 --
218227
bool(false)
@@ -294,6 +303,14 @@ bool(true)
294303
object_class::foo1
295304
bool(false)
296305
object_class::foo1
306+
-- Innerloop iteration 11 of Outerloop iteration 2 --
307+
bool(false)
308+
bool(false)
309+
bool(false)
310+
bool(false)
311+
no_member_class::__invoke
312+
bool(false)
313+
no_member_class::__invoke
297314
--- Outerloop iteration 3 ---
298315
-- Innerloop iteration 1 of Outerloop iteration 3 --
299316
bool(false)
@@ -375,6 +392,14 @@ bool(true)
375392
object_class::foo1
376393
bool(false)
377394
object_class::foo1
395+
-- Innerloop iteration 11 of Outerloop iteration 3 --
396+
bool(false)
397+
bool(false)
398+
bool(false)
399+
bool(false)
400+
contains_object_class::__invoke
401+
bool(false)
402+
contains_object_class::__invoke
378403
--- Outerloop iteration 4 ---
379404
-- Innerloop iteration 1 of Outerloop iteration 4 --
380405
bool(false)
@@ -456,6 +481,14 @@ bool(true)
456481
object_class::foo1
457482
bool(false)
458483
object_class::foo1
484+
-- Innerloop iteration 11 of Outerloop iteration 4 --
485+
bool(false)
486+
bool(false)
487+
bool(false)
488+
bool(false)
489+
contains_object_class::__invoke
490+
bool(false)
491+
contains_object_class::__invoke
459492
--- Outerloop iteration 5 ---
460493
-- Innerloop iteration 1 of Outerloop iteration 5 --
461494
bool(true)
@@ -537,6 +570,14 @@ bool(true)
537570
object_class::foo1
538571
bool(false)
539572
object_class::foo1
573+
-- Innerloop iteration 11 of Outerloop iteration 5 --
574+
bool(false)
575+
bool(false)
576+
bool(false)
577+
bool(false)
578+
object_class::__invoke
579+
bool(false)
580+
object_class::__invoke
540581
--- Outerloop iteration 6 ---
541582
-- Innerloop iteration 1 of Outerloop iteration 6 --
542583
bool(false)
@@ -618,6 +659,14 @@ bool(true)
618659
object_class::foo1
619660
bool(false)
620661
object_class::foo1
662+
-- Innerloop iteration 11 of Outerloop iteration 6 --
663+
bool(false)
664+
bool(false)
665+
bool(false)
666+
bool(false)
667+
no_member_class::__invoke
668+
bool(false)
669+
no_member_class::__invoke
621670
--- Outerloop iteration 7 ---
622671
-- Innerloop iteration 1 of Outerloop iteration 7 --
623672
bool(true)
@@ -699,6 +748,14 @@ bool(true)
699748
object_class::foo1
700749
bool(false)
701750
object_class::foo1
751+
-- Innerloop iteration 11 of Outerloop iteration 7 --
752+
bool(false)
753+
bool(false)
754+
bool(false)
755+
bool(false)
756+
object_class::__invoke
757+
bool(false)
758+
object_class::__invoke
702759
--- Outerloop iteration 8 ---
703760
-- Innerloop iteration 1 of Outerloop iteration 8 --
704761
bool(false)
@@ -780,3 +837,10 @@ bool(true)
780837
object_class::foo1
781838
bool(false)
782839
object_class::foo1
840+
-- Innerloop iteration 11 of Outerloop iteration 8 --
841+
bool(false)
842+
bool(false)
843+
bool(false)
844+
bool(false)
845+
846+
bool(false)

0 commit comments

Comments
 (0)