Request processing pipeline
Increase or decrease the function needs to be reorganized corresponding process, i.e., the order to instantiate an object; Laravel framework is automated instantiated by the Service Container,
function calls between instances also by the closure function to complete, where we for simplicity, we will still function to prevent the instantiation process, only the
completion of the simulation by the closure function decorator pattern , to achieve the requested processing pipeline
Before understanding the code, first look array_reduce
array_reduce
array_reduce — 用回调函数迭代地将数组简化为单一的值
Explanation
array_reduce ( array $array , callable $callback [, mixed $initial = NULL ] ) : mixed
array_reduce () callback function callback iteratively applied to the array in the array each cell, so as to simplify the array to a single value.
parameter
array
输入的array
callback
callback( mixed $carry , mixed $item ) : mixed
carry
携带上次迭代里的值; 如果本次迭代是第一次,那么这个值是 initial。
item
携带了本次迭代的值。
initial
如果指定了可选参数 initial,该参数将在处理开始前使用,或者当处理结束,数组为空时的最后一个结果。
return value
Return result value
initial parameters, array_reduce () returns NULL
<?php
interface Middleware
{
public static function handle(Closure $next);
}
class VerifyCsrfToken implements Middleware
{
public static function handle(Closure $next)
{
echo "verify Csr Token ".'<br>';
$next();
}
}
class ShareErrorFromSession implements Middleware
{
public static function handle(Closure $next)
{
echo "share it if the variable of 'error' is existing in SESSION" . '<br>';
$next();
}
}
class StartSession implements Middleware
{
public static function handle(Closure $next)
{
echo "starting a SESSION, Getting data" .'<br>';
$next();
echo "saving data, Closing a Session" .'<br>';
}
}
class AddQueuedCookiesToResponse implements Middleware
{
public static function handle(Closure $next)
{
$next();
echo "adding a cookie for next request" .'<br>';
}
}
class EncryptCookies implements Middleware
{
public static function handle(Closure $next)
{
echo "Decrypting Cookies for input request" .'<br>';
$next();
echo "Encrypt cookie for output response" .'<br>';
}
}
class CheckForMaintenceMode implements Middleware
{
public static function handle(Closure $next)
{
echo "checking the state of program is maintenance mode" .'<br>';
$next();
}
}
function getSlice()
{
return function($stack, $pipe){
return function() use ($stack, $pipe){
return $pipe::handle($stack);
};
};
}
function then()
{
$pipe = [
"CheckForMaintenceMode",
"EncryptCookies",
"AddQueuedCookiesToResponse",
"StartSession",
"ShareErrorFromSession",
"VerifyCsrfToken",
];
$firstSlice = function(){
echo "take request submit to router , and return the response".'<br>';
};
$pipe = array_reverse($pipe);
call_user_func(
array_reduce($pipe, getSlice(), $firstSlice)
);
}
then();
Export
checking the state of programer is maintenance mode
Decrypting Cookies for input request
starting a SESSION, Getting data
share it if the variable of 'error' is existing in SESSION
verify Csr Token
take request submit to router , and return the response
saving data, Closing a Session
adding a cookie for next request
Encrypt cookie for output response
Examples of the main part of the code is upper call_user_func(array_reduce($pipe, getSlice(), $firstSlice)
portion appreciated; this part is the most obscure, difficult to understand portion;
The array_reduce()
interface function attributes (previous article has been presented in detail), part of this analysis drawing program execution;
首先得理解array_reduce这个接口的使用,从上图可知array_reduce执行完成后,最后返回的是一个包含了6层的闭包对象;
call_user_func执行的时候从最外面那一层开始执行,此时$pipe
的值为CheckForMaintenanceMode
也就是首先调用
CheckForMaintenanceMode类的静态方法handle(),所以我们看到的第一条输出是checking the state of programer is maintenance mode
;
执行$next()
时,其实就是执行CheckForMaintenanceMode::handle()
方法中传入的闭包对象;
从图中可知,CheckForMaintenanceMode::handle($stack)
中的$stack
值是包含5层的闭包对象,而此时$pipe
的值为EncryptCookies
;
即执行EncryptCookies::handle($stack)
返回输出Decrypting Cookies for input request
;
以此类推就可以很容易分析上述出输出结果;