diff --git a/Zend/tests/closure_063.phpt b/Zend/tests/closure_063.phpt new file mode 100644 index 0000000000000..c1d9c968a9da0 --- /dev/null +++ b/Zend/tests/closure_063.phpt @@ -0,0 +1,71 @@ +--TEST-- +Closure 063: Checking that closure is static +--FILE-- +getStaticClosure(); +$nonstaticScoped = $a->getNonStaticClosure(); + +function function_callable() {} + +$nonstaticFromFunction = Closure::fromCallable('function_callable'); + +class B { + function nonStaticMethod() {} + static function staticMethod() {} +} + +$staticFromMethod = Closure::fromCallable([B::class, 'staticMethod']); +$nonstaticFromMethod = Closure::fromCallable([new B(), 'nonStaticMethod']); + +echo "Unscoped Closure\n"; +var_dump($staticUnscoped->isStatic()); +var_dump($nonstaticUnscoped->isStatic()); +echo "\n"; + +echo "Scoped Closure\n"; +var_dump($staticScoped->isStatic()); +var_dump($nonstaticScoped->isStatic()); +echo "\n"; + +echo "From Callable Function\n"; +var_dump($nonstaticFromFunction->isStatic()); +echo "\n"; + +echo "From Callable Method\n"; +var_dump($staticFromMethod->isStatic()); +var_dump($nonstaticFromMethod->isStatic()); +echo "\n"; + +echo "Done\n"; +?> +--EXPECTF-- +Unscoped Closure +bool(true) +bool(false) + +Scoped Closure +bool(true) +bool(false) + +From Callable Function +bool(false) + +From Callable Method +bool(true) +bool(false) + +Done diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 5ae122b7f94ab..1dd6212330399 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -193,6 +193,17 @@ ZEND_METHOD(Closure, call) } /* }}} */ +ZEND_METHOD(Closure, isStatic) /* {{{ */ +{ + ZEND_PARSE_PARAMETERS_NONE(); + + zend_closure *closure = (zend_closure *) Z_OBJ_P(ZEND_THIS); + zend_function *func = &closure->func; + + RETURN_BOOL(func->common.fn_flags & ZEND_ACC_STATIC); +} +/* }}} */ + static void do_closure_bind(zval *return_value, zval *zclosure, zval *newthis, zend_object *scope_obj, zend_string *scope_str) { zend_class_entry *ce, *called_scope; diff --git a/Zend/zend_closures.stub.php b/Zend/zend_closures.stub.php index 3d451e58b69b2..e7ae8b701617e 100644 --- a/Zend/zend_closures.stub.php +++ b/Zend/zend_closures.stub.php @@ -13,6 +13,8 @@ public static function bind( object|string|null $newScope = "static" ): ?Closure {} + public function isStatic(): bool {} + public function bindTo(?object $newThis, object|string|null $newScope = "static"): ?Closure {} public function call(object $newThis, mixed ...$args): mixed {} diff --git a/Zend/zend_closures_arginfo.h b/Zend/zend_closures_arginfo.h index 888e4994a08c6..f4e624c19951e 100644 --- a/Zend/zend_closures_arginfo.h +++ b/Zend/zend_closures_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7c4df531cdb30ac4206f43f0d40098666466b9a6 */ + * Stub hash: 1e2c3090490b59afcf468d485fd44ef7d005bf41 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Closure___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -10,6 +10,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Closure_bind, 0, 2, Closure ZEND_ARG_TYPE_MASK(0, newScope, MAY_BE_OBJECT|MAY_BE_STRING|MAY_BE_NULL, "\"static\"") ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Closure_isStatic, 0, 0, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Closure_bindTo, 0, 1, Closure, 1) ZEND_ARG_TYPE_INFO(0, newThis, IS_OBJECT, 1) ZEND_ARG_TYPE_MASK(0, newScope, MAY_BE_OBJECT|MAY_BE_STRING|MAY_BE_NULL, "\"static\"") @@ -27,6 +30,7 @@ ZEND_END_ARG_INFO() ZEND_METHOD(Closure, __construct); ZEND_METHOD(Closure, bind); +ZEND_METHOD(Closure, isStatic); ZEND_METHOD(Closure, bindTo); ZEND_METHOD(Closure, call); ZEND_METHOD(Closure, fromCallable); @@ -35,6 +39,7 @@ ZEND_METHOD(Closure, fromCallable); static const zend_function_entry class_Closure_methods[] = { ZEND_ME(Closure, __construct, arginfo_class_Closure___construct, ZEND_ACC_PRIVATE) ZEND_ME(Closure, bind, arginfo_class_Closure_bind, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(Closure, isStatic, arginfo_class_Closure_isStatic, ZEND_ACC_PUBLIC) ZEND_ME(Closure, bindTo, arginfo_class_Closure_bindTo, ZEND_ACC_PUBLIC) ZEND_ME(Closure, call, arginfo_class_Closure_call, ZEND_ACC_PUBLIC) ZEND_ME(Closure, fromCallable, arginfo_class_Closure_fromCallable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)