mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Implement Closure::getCurrent() to retrieve current closure
Fixes GH-18163 Closes GH-18167
This commit is contained in:
@@ -421,6 +421,7 @@ PHP 8.5 UPGRADE NOTES
|
||||
. The clone language construct is now a function and supports reassigning
|
||||
(readonly) properties during cloning via the new $withProperties parameter.
|
||||
RFC: https://wiki.php.net/rfc/clone_with_v2
|
||||
. Added Closure::getCurrent() to receive currently executing closure.
|
||||
|
||||
- Curl:
|
||||
. curl_multi_get_handles() allows retrieving all CurlHandles current
|
||||
|
||||
64
Zend/tests/closures/closure_get_current.phpt
Normal file
64
Zend/tests/closures/closure_get_current.phpt
Normal file
@@ -0,0 +1,64 @@
|
||||
--TEST--
|
||||
Closure::getCurrent()
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$i = 1;
|
||||
|
||||
$c = function ($p) use (&$i) {
|
||||
$self = Closure::getCurrent();
|
||||
var_dump($p, $i);
|
||||
$i++;
|
||||
if ($p < 10) {
|
||||
$self($p + 1);
|
||||
}
|
||||
};
|
||||
|
||||
$c(1);
|
||||
var_dump($i);
|
||||
|
||||
function fail() {
|
||||
Closure::getCurrent();
|
||||
}
|
||||
|
||||
try {
|
||||
fail();
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
function foo() {
|
||||
var_dump(Closure::getCurrent());
|
||||
}
|
||||
|
||||
try {
|
||||
foo(...)();
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(1)
|
||||
int(2)
|
||||
int(2)
|
||||
int(3)
|
||||
int(3)
|
||||
int(4)
|
||||
int(4)
|
||||
int(5)
|
||||
int(5)
|
||||
int(6)
|
||||
int(6)
|
||||
int(7)
|
||||
int(7)
|
||||
int(8)
|
||||
int(8)
|
||||
int(9)
|
||||
int(9)
|
||||
int(10)
|
||||
int(10)
|
||||
int(11)
|
||||
Current function is not a closure
|
||||
Current function is not a closure
|
||||
@@ -418,6 +418,23 @@ ZEND_METHOD(Closure, fromCallable)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_METHOD(Closure, getCurrent)
|
||||
{
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
zend_execute_data *prev_ex = EX(prev_execute_data);
|
||||
|
||||
if (!prev_ex
|
||||
|| !prev_ex->func
|
||||
|| (prev_ex->func->common.fn_flags & (ZEND_ACC_CLOSURE|ZEND_ACC_FAKE_CLOSURE)) != ZEND_ACC_CLOSURE) {
|
||||
zend_throw_error(NULL, "Current function is not a closure");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
zend_object *obj = ZEND_CLOSURE_OBJECT(prev_ex->func);
|
||||
RETURN_OBJ_COPY(obj);
|
||||
}
|
||||
|
||||
static ZEND_COLD zend_function *zend_closure_get_constructor(zend_object *object) /* {{{ */
|
||||
{
|
||||
zend_throw_error(NULL, "Instantiation of class Closure is not allowed");
|
||||
|
||||
@@ -21,4 +21,6 @@ final class Closure
|
||||
public function call(object $newThis, mixed ...$args): mixed {}
|
||||
|
||||
public static function fromCallable(callable $callback): Closure {}
|
||||
|
||||
public static function getCurrent(): Closure {}
|
||||
}
|
||||
|
||||
7
Zend/zend_closures_arginfo.h
generated
7
Zend/zend_closures_arginfo.h
generated
@@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: e3b480674671a698814db282c5ea34d438fe519d */
|
||||
* Stub hash: e0626e52adb2d38dad1140c1a28cc7774cc84500 */
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Closure___construct, 0, 0, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
@@ -24,11 +24,15 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Closure_fromCallable, 0, 1,
|
||||
ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Closure_getCurrent, 0, 0, Closure, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_METHOD(Closure, __construct);
|
||||
ZEND_METHOD(Closure, bind);
|
||||
ZEND_METHOD(Closure, bindTo);
|
||||
ZEND_METHOD(Closure, call);
|
||||
ZEND_METHOD(Closure, fromCallable);
|
||||
ZEND_METHOD(Closure, getCurrent);
|
||||
|
||||
static const zend_function_entry class_Closure_methods[] = {
|
||||
ZEND_ME(Closure, __construct, arginfo_class_Closure___construct, ZEND_ACC_PRIVATE)
|
||||
@@ -36,6 +40,7 @@ static const zend_function_entry class_Closure_methods[] = {
|
||||
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)
|
||||
ZEND_ME(Closure, getCurrent, arginfo_class_Closure_getCurrent, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user