Anonymous self-starting function without variable declaration

I want to call an anonymous function without declaring a variable for it.

I know this is a working example:

$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); 

But I want to call and disable it automatically:

 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); 

But this example will not work, because our function does not have a name. Is there any solution or do you know any solution to solve this problem?


PS: Suppose that $input is the following array: ["Hello, ", "World!"] .

The conclusion should be:

 Hello, World! 

Update # 1:

As soon as this is an example, call_user_func_array(function () { ... }, $input) not the solution I'm looking for.

And it will not work if I have $input like [["Hello, ", "World"], "!"] .


Update # 2:

Another solution I'm not looking for is debug_backtrace()[1]['args'][0]->__invoke($current); . I think this is ugly enough to be used for debugging only. :) Thanks @fschmengler .

And another form of this call_user_func(debug_backtrace()[1]['args'][0], $current)); .


Update # 3:

Another solution written by @UlrichEckhardt injects an anonymous function into another anonymous function. I think by canceling a previously declared function variable - for example. the first example is cleaner and shorter. But this is also a solution.

 function () { $f = function ($param) use ($f) { // use $f here } return $f; }() 
+5
source share
2 answers

You can access the closure using debug_backtrace() and use __invoke() to call it to call it using call_user_func() as before:

 $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); 

But, in my opinion, the first version, where you assign the closure of a variable, is more readable, and I see no arguments against it, except for personal taste.

Update: it should be call_user_func() again, not __invoke() , so args [0] refers to the closure for each recursion level

+3
source

Write a closure returning the closure you want and name it:

 function () { $f = function ($param) use ($f) { // use $f here } return $f; }() 

I'm actually not sure if PHP is able to define and call a function in one step, you may have to use call_user_func() instead to get around your language flaws here. As an aside, there are much better ways to write code obfuscation, and if this is surprisingly not your goal, there may be even clearer alternatives .; -)

+2
source

Source: https://habr.com/ru/post/1212375/


All Articles