稀裡糊塗系列之閉包中介軟體

符權發表於2019-03-04

概述

一個框架中的中介軟體是必不可少的一部分。

以前對這方面是有點懵逼的,只知其然但不知其所以然,在網上看了一些大佬寫的文章後,有點想法,希望對初學者有所幫助。

中介軟體就是給應用外面加一個 “結界” ,在進入應用之前,要經過結界;離開應用之後,也要經過它。

怎麼感覺我越說越迷啊。。。。。。

step-0

先看一段很簡單很普通的程式碼。

function main()
{
    // 前置操作,例如對身份的驗證之類
    echo `this is before middleware`;
    
    // 業務邏輯操作
    // ....
    echo `this body of application`;
    
    // 後置操作,發射響應包之類
    echo `this is back middleware`;
}

// 執行
main();
複製程式碼

step-1

然後,我們試著把前置操作和後置操作從業務邏輯部分抽離出來,用到了閉包,也是本次的主角:

$before_middleware = function () {
    echo `this is before middleware`;
};

$back_middleware = function () {
    echo `this is back middleware`;
};

$body = function () {
    echo `this body of application`;
};

function main($fmw, $body, $bmw)
{
    $fmw();
    $body();
    $bmw();
}

// 執行
main($before_middleware, $back_middleware);
複製程式碼

step-2

“我褲子都脫了,你就給我看這個??”

哈哈,好吧,這只是為了從無到有展現我的心路歷程,也是強調基礎的重要性,畢竟那些了不起的應用和框架都是由基礎的語法構建的。還有一個更重要的原因,就是先讓大家適應一下php的閉包。

來點不一樣的寫法:

$before_middleware = function ($body) {
    return function () use ($body) {
        echo `this is before middleware` . "
";
        return $body();
    };
};

$back_middleware = function ($body) {
    return function () use ($body) {
        $bd = $body();
        echo `this is back middleware` . "
";
        return $bd;
    };
};

$body = function () {
    echo `this body of application` . "
";
};

// 準備
$body = $before_middleware($body);
$body = $back_middleware($body);

// 執行
$body();
複製程式碼

step-3

是不是感覺有點意思了??
然後再把 “準備” 步驟進行一下封裝,比如說這樣:

$before_middleware = function ($body) {
    return function () use ($body) {
        echo `this is before middleware` . "
";
        return $body();
    };
};

$back_middleware = function ($body) {
    return function () use ($body) {
        $bd = $body();
        echo `this is back middleware` . "
";
        return $bd;
    };
};

$body = function () {
    echo `this body of application` . "
";
};

// 準備
$conf = array(
    $before_middleware,
    $back_middleware,
);
function ready($body, $conf)
{
    foreach ($conf as $midd) {
        $body = $midd($body);
    }
    
    return $body;
}

// 執行
$res = ready($body, $conf);
$res();
複製程式碼

最後

這個是我便於理解,所以寫的超簡化版本,也就是介紹一下原理。

想一下,這個前置和後置的操作是不是還可以做一個抽象??試試把真正要執行的中介軟體函式作為引數傳入,從而代替 echo 的位置呢??或者在這個之上再做一層閉包封裝??

額,貌似還是沒講明白……希望對小白同學有所幫助~~

我看了網上的版本,除了閉包實現的中介軟體,yield 這個不怎麼常用的東西也可以。正好今天公司裡,我寫的一個指令碼因為一次性從資料庫里拉的資料量大,導致了記憶體的fatal錯誤。打算對 yield 做一次系統學習。

欲知後事如何,且聽下回分解!

相關文章