成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

模仿KOA,用php來(lái)寫(xiě)一個(gè)極簡(jiǎn)的開(kāi)發(fā)框架

LiangJ / 3278人閱讀

摘要:歡迎感興趣的去了解和提出建議,也歡迎地址期望用法先來(lái)看看我要怎么用這個(gè)框架基本上跟類(lèi)似,先一個(gè)對(duì)象,使用方法添加中間件,支持閉包或外部文件。

nodejs的koa可以說(shuō)是非常受歡迎的,特別是其“洋蔥模型”應(yīng)該用過(guò)的人印象都比較深,下面就嘗試用php來(lái)實(shí)現(xiàn)一個(gè)。

注:本文是PHPec框架的最原始思路版本。PHPec是在此基礎(chǔ)上完善編寫(xiě)出來(lái)的一個(gè)極簡(jiǎn)的輕量級(jí)開(kāi)發(fā)框架,除了提供中間件調(diào)用模式外,同時(shí)提供了常見(jiàn)的自動(dòng)路由功能,目前 已在github上發(fā)布了最初版本。歡迎感興趣的去了解和提出建議,也歡迎star. 地址:https://github.com/tim1020/PHPec
期望用法

先來(lái)看看我要怎么用“這個(gè)框架”?

require "app.php";
$app = new App();

$app -> use(function($ctx){
    $ctx -> body.= ">m1";
    $ctx -> next();
    $ctx -> body .= ">m1 end";
});

$app -> use("Middleware2");

$app -> run();

基本上跟koa類(lèi)似,先new一個(gè)app對(duì)象,使用use方法添加中間件,支持閉包或外部文件。

$ctx支持注入所需的各種參數(shù),方便各中間件共用。

完整代碼
//app.php
class App{
    private $m = array();
    private $ctx = array();
    function next(){
        $f = $this -> c -> current();
        if(!$f) return;
        $this -> c -> next();
        $f($this);
    }
    function run(){
        $this -> c = $this -> _gen();
        $this -> next();
    }
    private function _gen(){
        foreach($this -> m as $v){
            yield $v;
        }
    }
    private function _add($m){
        if(!empty($this->m) && $this -> m[count($this->m) -1] === false) return;
        if(!$m){
            $this -> m[] = false;
        }elseif(($m instanceof Closure)){
            $this -> m[] = $m;
        }else{
            $m = $this -> _load($m);
            if(!function_exists($m)){
               throw new Exception("middleware error");
            }
            else $this -> m[] = $m;
        }
    }
    //處理文件加載,返回執(zhí)行函數(shù)(如需要,可加入命名空間處理)
    private function _load($m){
        $f = "./middleware/".$m.".php";
        if(!file_exists($f)) throw new Exception("middleware error");
        require $f;
        return $m;
    }
    function __call($m,$v){
        if("use" == $m){
            $p = isset($v[0]) ? $v[0] : "";
            $this -> _add($p);
        }else{
            throw new Exception("method not exists");
        }
    }
    function __set($k,$v){
        $this -> ctx[$k] = $v;
    }
    function __get($k){
        return isset($this -> ctx[$k]) ? $this -> ctx[$k] : NULL;
    }
}

沒(méi)錯(cuò),這就是全部的代碼。

代碼講解 use方法

use可以加入閉包或外部文件,且php5不支持use作為方法名,這里用__call來(lái)實(shí)現(xiàn)重載,當(dāng)調(diào)用use時(shí)由__call來(lái)調(diào)用私有的_add方法。

_add對(duì)傳進(jìn)來(lái)的參數(shù)作判斷,如果是字符串,表示外部加載,則去判斷文件和處理函數(shù)是否存在和有效,然后將處理函數(shù)加到中間件隊(duì)列。

這里面如果use()傳遞空參數(shù),表示忽略后面的中間件。
run方法

添加完中間件后,執(zhí)行$app -> run()方法運(yùn)行,來(lái)看看是怎么執(zhí)行的:

調(diào)用私有的_gen來(lái)生成一個(gè)生成器,該生成器可以迭代返回隊(duì)列中的中間件處理函數(shù)。

調(diào)用next方法執(zhí)行下一個(gè)中間件(這里即第一個(gè)入口)

2.1 調(diào)用生成器的current方法獲得當(dāng)前的處理函數(shù)

2.2 執(zhí)行該函數(shù)(傳遞$this作為參數(shù),即$ctx),并調(diào)用生成器的next方法后移到下一個(gè)處理函數(shù)

直到生成器沒(méi)有返回時(shí)結(jié)束。

中間件中需調(diào)用$ctx-> next()將控制權(quán)交到下一個(gè)中間件,從而迭代完所有的中間件。
__get和__set方法

提供了__get和__set方法,是方便在中間件中使用$ctx直接設(shè)置和訪問(wèn)未經(jīng)定義的值。如:

$ctx -> body = "hello";
$ctx -> tplName = "a.tpl";
That is all

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/26312.html

相關(guān)文章

  • 一個(gè)簡(jiǎn)的基于swoole常駐內(nèi)存框架

    摘要:于是打算做一個(gè)擁有非常好用的路由和又非常簡(jiǎn)單的框架。但也有一些自己的特色,例如支持自動(dòng)化緩存自動(dòng)化讀寫(xiě)刷新保持與數(shù)據(jù)庫(kù)同步,對(duì)外使用無(wú)感知。例如協(xié)議服務(wù)器地址遠(yuǎn)程的類(lèi)不設(shè)置默認(rèn)為當(dāng)前類(lèi)名其中類(lèi)在框架里。 背景 在用過(guò)laravel框架,發(fā)現(xiàn)它的路由和數(shù)據(jù)庫(kù)ORM確實(shí)非常好用,但是整體確實(shí)有點(diǎn)慢,執(zhí)行到控制器大于需要耗時(shí)60ms左右。于是打算做一個(gè)擁有非常好用的路由和orm又非常簡(jiǎn)單的框...

    Steve_Wang_ 評(píng)論0 收藏0
  • 簡(jiǎn)的Restful框架推薦->Resty

    摘要:源碼鏈接開(kāi)發(fā)文檔如果你還不是很了解,或者認(rèn)為只是一種規(guī)范不具有實(shí)際意義,推薦一篇兩年前的文章設(shè)計(jì)最佳實(shí)踐和的一篇極其理論的文章理解本真的架構(gòu)風(fēng)格雖然有點(diǎn)老,介紹的也很簡(jiǎn)單,大家權(quán)當(dāng)了解,的更多好處,還請(qǐng)擁有一樣的的簡(jiǎn)潔設(shè)計(jì),使用更簡(jiǎn)單的框架 源碼鏈接:Resty 開(kāi)發(fā)文檔 如果你還不是很了解restful,或者認(rèn)為restful只是一種規(guī)范不具有實(shí)際意義,推薦一篇osc兩年...

    JerryC 評(píng)論0 收藏0
  • React組件設(shè)計(jì)實(shí)踐總結(jié)05 - 狀態(tài)管理

    摘要:要求通過(guò)要求數(shù)據(jù)變更函數(shù)使用裝飾或放在函數(shù)中,目的就是讓狀態(tài)的變更根據(jù)可預(yù)測(cè)性單向數(shù)據(jù)流。同一份數(shù)據(jù)需要響應(yīng)到多個(gè)視圖,且被多個(gè)視圖進(jìn)行變更需要維護(hù)全局狀態(tài),并在他們變動(dòng)時(shí)響應(yīng)到視圖數(shù)據(jù)流變得復(fù)雜,組件本身已經(jīng)無(wú)法駕馭。今天是 520,這是本系列最后一篇文章,主要涵蓋 React 狀態(tài)管理的相關(guān)方案。 前幾篇文章在掘金首發(fā)基本石沉大海, 沒(méi)什么閱讀量. 可能是文章篇幅太長(zhǎng)了?掘金值太低了? ...

    ideaa 評(píng)論0 收藏0
  • VuePress來(lái)搭建一個(gè)簡(jiǎn)的靜態(tài)網(wǎng)站

    摘要:馨客棧前端導(dǎo)航享受的開(kāi)發(fā)體驗(yàn),在中使用組件,同時(shí)可以使用來(lái)開(kāi)發(fā)自定義主題。馨客棧每日分享為每個(gè)頁(yè)面預(yù)渲染生成靜態(tài)的,同時(shí)在頁(yè)面被加載的時(shí)候,將作為運(yùn)行。 VuePress學(xué)習(xí) 全局安裝前我們需要Git和node這兩個(gè)軟件,關(guān)于怎么安裝可以我之前hexo的視頻教程 假如這兩個(gè)都沒(méi)有安裝好,那么下面就不需要看了哈,棧友們 全局安裝 首先我們先全局安裝一下 npm stall -g vuep...

    BetaRabbit 評(píng)論0 收藏0
  • VuePress來(lái)搭建一個(gè)簡(jiǎn)的靜態(tài)網(wǎng)站

    摘要:馨客棧前端導(dǎo)航享受的開(kāi)發(fā)體驗(yàn),在中使用組件,同時(shí)可以使用來(lái)開(kāi)發(fā)自定義主題。馨客棧每日分享為每個(gè)頁(yè)面預(yù)渲染生成靜態(tài)的,同時(shí)在頁(yè)面被加載的時(shí)候,將作為運(yùn)行。 VuePress學(xué)習(xí) 全局安裝前我們需要Git和node這兩個(gè)軟件,關(guān)于怎么安裝可以我之前hexo的視頻教程 假如這兩個(gè)都沒(méi)有安裝好,那么下面就不需要看了哈,棧友們 全局安裝 首先我們先全局安裝一下 npm stall -g vuep...

    charles_paul 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<