PHP code for detailed explanation?

post a piece of code I saw on Zhihu, but I haven"t figured it out for a long time. Ask the great god for a popular explanation:

<?php

namespace App;

interface Middleware
{
    public function handle($next);
}

class Session implements Middleware
{
    public function handle($next)
    {
        echo "<br/>Session Start<br/>";
        $next();
        echo "<br/>Session End<br/>";
    }
}

class Mysql implements Middleware
{
    public function handle($next)
    {
        echo "<br/>Mysql Start<br/>";
        $next();
        echo "<br/>Mysql end<br/>";
    }
}

function run($next, $step)
{
    return function () use ($next, $step) {
        call_user_func_array([new $step, "handle"], [$next]);
    };
}

$class    = [Session::class, Mysql::class];
$callback = array_reduce($class, "App\run", function () {});
$callback();

run results

Mysql Start

Session Start

Session End

Mysql end

Php
Mar.02,2021

like the following question, I don't want to repeat it.
https://codeshelper.com/q/10.

first of all, it is like this. Let's take a look at the following code to understand

<?php
function myfunction($v1,$v2)
{
return $v1+$v2;
}
$a=array(10,15,20);
print_r(array_reduce($a,"myfunction",5)); //50
?>

the above result is 50. So what is its process? We improve the code

function myfunction($v1, $v2)
{
    var_dump($v1, $v2);
    return $v1 + $v2;
}

$a = array(10, 15, 20);
print_r(array_reduce($a, "myfunction", 5)); //50
echo "\n";

then you can see the following output

int(5)
int(10)
int(15)
int(15)
int(30)
int(20)
50

the first v1 = 5recoveryv2 = 10;
the second v1 = 15 (the value returned by the previous one), v2 = 15; the value of $a [1];
the third v1 = 30 (last return value), v2 = 20; the value of $a [2];

< hr > < hr >

now answer the subject's question:

the above example myfunction returns a numeric value, but the question of the subject run method returns a function , which is important.

now let's think of array_reduce ($class, 'App\ run', function () {}); the third function as A .

now execute
first step run (A, Session::class according to the principle of array_reduce method), return new function B (especially important, run method knowledge returns a function, the function will not execute )
second step run (B, Mysql::class), return new function C (at this time function C will be assigned to $callback )

After the

array_reduce function is executed, the final return is function C, and the last line of code $callback (); is the execution of function C.

now start to push back

// C$nextB$stepMysql::class
function($next, $step) {
    call_user_func_array([new $step, 'handle'], [$next]);
};

// 
call_user_func_array([new Mysql, 'handle'], [B]);

// BMysqlhandle$nextB
public function handle($next)
{
    echo "<br/>Mysql Start<br/>";
    $next();
    echo "<br/>Mysql end<br/>";
}

// <br/>Mysql Start<br/>BB
// BA`function() {}`
call_user_func_array([new Session, 'handle'], [A]);

// 
echo "<br/>Session Start<br/>";
function() {};
echo "<br/>Session End<br/>";

// BC<br/>Mysql end<br/>

// 
echo "<br/>Mysql Start<br/>";
echo "<br/>Session Start<br/>";
function() {};
echo "<br/>Session End<br/>";
echo "<br/>Mysql end<br/>";

all right, the story is done.

Menu