mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Implement Closure::getCurrent() to retrieve current closure
Fixes GH-18163 Closes GH-18167
This commit is contained in:
parent
d20f4fca69
commit
eb65ec41b7
5 changed files with 90 additions and 1 deletions
|
@ -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
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue