Я хочу вызвать анонимную функцию, не объявляя переменную для нее.
Я знаю, что это рабочий пример:
$foo = function ($bar) use ($foo) {
if (is_array($bar)) {
foreach ($bar AS $current) {
$foo($current);
}
}
else {
print($bar);
}
};
$foo($input);
# Unset variable cause we won't need it anymore
# and we like to have a lot of free memory.
unset($foo);
Но я хочу позвонить и сбросить его автоматически:
call_user_func(function ($bar) {
if (is_array($bar)) {
foreach ($bar AS $current) {
# This won't work
# as our function doesn't have any name.
call_user_func(__FUNCTION__, $current);
}
}
else {
print($bar);
}
}, $input);
PS: предположим, что $input
это следующий массив: ["Hello, ", "World!"]
,
Начиная с этого, результат должен быть:
Hello,
World!
Обновление № 1:
Как это только пример, call_user_func_array(function () { ... }, $input)
это не решение, которое я ищу.
И это не будет работать, если у меня есть $input
лайк [["Hello, ", "World"], "!"]
,
Обновление № 2:
Другое решение я не ищу это debug_backtrace()[1]['args'][0]->__invoke($current);
, Я думаю, что это достаточно уродливо, чтобы использовать для отлаживать только. 🙂
Благодаря @fschmengler.
И другая форма этого call_user_func(debug_backtrace()[1]['args'][0], $current));
,
Обновление № 3:
Другое решение, написанное @UlrichEckhardt встраивает анонимную функцию в другую анонимную функцию. Я думаю, сбросив ранее объявленную переменную функции — например. Первый пример — и чище, и короче. Но это тоже решение.
function () {
$f = function ($param) use ($f) {
// use $f here
}
return $f;
}()
Доступ к закрытию возможен с debug_backtrace()
а также использование позвони с __invoke()
называть этоcall_user_func()
как прежде:
$input = ["Hello, ", "World!"];
call_user_func(function ($bar) {
if (is_array($bar)) {
foreach ($bar AS $current) {
call_user_func(debug_backtrace()[1]['args'][0], $current));
}
}
else {
print($bar);
}
}, $input);
Но, по моему мнению, первая версия, в которой вы назначаете закрытие переменной, более читабельна, и я не вижу никаких аргументов против этого, кроме личного вкуса.
Обновить: должно быть call_user_func()
опять не __invoke()
, так что args [0] ссылается на замыкание для каждого уровня рекурсии
Напишите закрытие, возвращающее желаемое закрытие, и назовите это:
function () {
$f = function ($param) use ($f) {
// use $f here
}
return $f;
}()
Я на самом деле не уверен, что PHP способен определять и вызывать функцию за один шаг, возможно, вам придется использовать call_user_func()
вместо этого, чтобы обойти недостатки вашего языка здесь. Помимо этого, есть гораздо лучшие способы написания запутанного кода, и, если это не является вашей целью, могут быть даже более ясные альтернативы. 😉