middleware
的原理就是「管道」。
管道 (pipe)
管道類似水淨化過程中的層層過濾。
中介軟體的意思就是說,在接下來的邏輯之前,需要的操作。
例如江河之水我們不能直接喝,在輸出淨水之前有過濾細菌的機器。
那麼我們把輸出淨水的邏輯,封裝成一個匿名函式 $next
,然後只需要這樣:
$next = function(){
echo "輸出淨水";
}
$next2 = function($next){
echo "過濾細菌";
$next();
}
執行:
$next2();
輸出:
//過濾細菌
//輸出淨水
現在發現水裡有細沙,我們又引入了過濾細沙的機器,需要在目前過濾系統的之前執行。
$next3 = function($next2){
echo "過濾細沙";
$next2();
}
執行:
$next3();
輸出:
//過濾細沙
//過濾細菌
//輸出淨水
例項程式碼
$step1 = function ($next){
echo "第一步:過濾小石頭".PHP_EOL;
$next();
};
$step2=function ($next){
echo "第二步:過濾細沙".PHP_EOL;
$next();
};
$step3 = function ($next){
echo "第三步:過濾細菌".PHP_EOL;
$next();
};
$success = function (){
echo "最後:輸出純淨水".PHP_EOL;
};
$callback = function ($next,$step) {
return function () use ( $next, $step ) {
return $step($next);
};
};
$middleWares = [
$step1,
$step2,
$step3
];
$middleWares=array_reverse($middleWares); //將陣列元素順序反轉
call_user_func(
array_reduce($middleWares,$callback,$success)
);
//第一步:過濾小石頭 第二步:過濾細沙 第三步:過濾細菌 最後:輸出純淨水
array_reduce
array_reduce ( array $array , callable $callback [, mixed $initial = NULL ] ) : mixed
array_reduce() 將回撥函式 callback 迭代地作用到 array 陣列中的每一個單元中,從而將陣列簡化為單一的值。
解釋挺不容易明白,$array
就是中介軟體陣列;$callback
見上面的 $callback
變數,永遠返回一個閉包函式;$initial
意思是 init
初始值,也就是最終的目的「輸出淨水」$success
。
模擬laravel中介軟體
interface MiddleWare{
public static function handle(Closure $next);
}
class StartSession implements MiddleWare{
public static function handle( Closure $next ) {
echo '開啟 session'.'<br>';
$next();
echo '關閉 session'.'<br>';
}
}
class AddQueuedCookiesToResponse implements MiddleWare{
public static function handle( Closure $next ) {
$next();
echo '新增下一次請求的token'."<br>";
}
}
class EbcryptCookies implements MiddleWare{
public static function handle( Closure $next ) {
echo '對 cookie 加密'.'<br>';
$next();
echo '對 cookie 解密'.'<br>';
}
}
function getSlice(){
return function ($stack,$pipe){
return function () use ($stack,$pipe){
return $pipe::handle($stack);
};
};
}
function then() {
$pipes = [
'EbcryptCookies', //加密請求cookie
'AddQueuedCookiesToResponse', //新增下一次請求需要的cookie
'StartSession', //開啟session
];
$firstSlice=function(){echo '請求向路由器傳遞,返回相應'.'<br>';};
$pipes=array_reverse($pipes);
call_user_func(
array_reduce($pipes,getSlice(),$firstSlice)
);
}
then();
/*
對 cookie 加密
開啟 session
請求向路由器傳遞,返回相應
關閉 session
新增下一次請求的token
對 cookie 解密
*/
本作品採用《CC 協議》,轉載必須註明作者和本文連結