skip to Main Content

I’ve encountered this code, but I can’t understand its logic. Could someone explain why the output is the way it is?

<?php

$functions = [
    
    function($next) {
        
        echo 'A' .PHP_EOL;
        $next();
    },
    
    function($next) {
        
        echo 'B' .PHP_EOL;
        $next();
    },
    
    function($next) {
        
        echo 'C' .PHP_EOL;
        $next();
    }
    
];
    
$a = function() {
    
    echo 'Main Content' .PHP_EOL;
     
};

foreach($functions as $function) {
    
    $a = fn() => $function($a);
    
}

$a();

Output:

C
B
A
Main Content

2

Answers


  1. It’s a kind of reversed recursion, the code snippet is setting an initial callback function line 18 and then looping over the $functions array, overriding the old variable $a by the new function in the loop. At the end, the last function (the one with echo 'C' .PHP_EOL;) is being called, causing an initial call to the $next() callback line 14, which is – from the foreach loop – points to the b function, which is being called, causing the invocation of the $next() callback line 10 and so on. Until it reaches the initial function declaration.

    Login or Signup to reply.
  2. The code you provided looks like from some middleware, wherein the outer function must utilize the result of inner function to perform some task

    For simplicity sake I have converted the 3 iterations of the foreach loop into an equivalent code

    Now when the loop starts, on its 1st iteration it will be something like
    (For better clarity I used the "full-form" of anonymous function instead of the shorthand notation)

    $firstLoopFn = function($next) {
        echo 'A' .PHP_EOL;
        $next(); // <-- the origin $a function("Main Content") which does not call any other function
    }
    

    $firstLoopFn becomes the new $a in your original code

    What happens in the 2nd iteration? Same

    $secondLoopFn = function($next) {   
        echo 'B' .PHP_EOL;
        $next();  // <-- this is actually $firstLoopFn
    }
    

    $secondLoopFn becomes the new $a in your original code

    Similarly the 3rd iteration

    $thirdLoopFn = function($next) {   
        echo 'C' .PHP_EOL;
        $next();  // <-- this is actually $secondLoopFn
    }
    

    $thirdLoopFn becomes the new $a in your original code

    Now the order, it is nothing but similar to this

    $result = Function3rd( Function2d( Function1st( ... ) ) )
    

    Function3rd will run first the then Function2d and so on

    Please observe in your case the last iteration of foreach loop adds the final "layer" so it gets runs first (Function3rd here)

    Also the fact that echo precedes the call to inner function in the source code so it gets run before the inner function called, to simply say function prints first then calls the inner function

        thirdLoopFn( /*echo C */ 
            secondLoopFn(  /*echo B */ 
                firstLoopFn( /*echo A */ $a)
            )
        )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search