沒記錯的話,好像從nodejs的koa開始,web開發中的中介軟體模式就比較流行,本篇我們就來聊一下中介軟體。
習慣地, web的中介軟體是指“請求到達到業務邏輯處理之前”的處理模組,同樣,在業務邏輯處理完成到響應輸出之間的處理,也是“中介軟體”。
如圖:在業務邏輯之前的處理稱為前置處理中介軟體,在業務邏輯之後的處理稱為後置處理中介軟體
(因為業務邏輯通常由控制器來呼叫,所以,這裡用控制器代替了業務邏輯)
中介軟體
前置中介軟體主要用於攔截請求並進行相應的處理,比如:
請求引數加工 (安全過濾等)許可權認證路由路徑及引數計算後置中介軟體主要用於對響應結果進行處理,比如:
格式化輸出新增統一響應頭實現方式在作用上,我們劃分了前置中介軟體和後置中介軟體,在實現上,同一個中介軟體可以同時包括兩種處理,比如記錄處理耗時的中介軟體,在前置(請求到達)處理記錄一個時間點,在後置處理(請求結束前)再進行計算記錄。
以下是示意圖:
中介軟體執行示意圖
說明:
在應用中,我們使用一個類似佇列的結構來存放中介軟體,每一中介軟體通過$next來指向下一中介軟體。
Router和Dispatcher為框架自動新增的中介軟體,Router為預設的路由處理,新增在隊頭,Dispatcher為根據路由結果分派控制器,新增在隊尾。
下面來看具體實現。
中介軟體抽象類先定義一箇中間件基類,供框架內建中介軟體以及應用開發者進行自定義中介軟體時繼承使用,用來約束中介軟體長什麼樣子:
中介軟體基類
程式碼說明:
1.通過“use DITrait”注入通用物件,則繼承自該基類的中介軟體均可以直接用“DITrait”中注入的物件和方法。
2.使用抽象類並定義了抽象方法,保證中介軟體均需實現handle方法。
3.setNext()方法用來繫結下一中介軟體,在往APP中新增中介軟體時被呼叫
4.next()方法,進入到下一中介軟體處理
5.後續我們再在DITrait中實現注入service的功能,可以在中介軟體中直接呼叫service進行處理
內建中介軟體內建中介軟體即比較通用的內建在自己框架中的中介軟體,繼承自框架的Middleware基類。
內建中介軟體放在框架程式碼的middleware目錄,先在框架中建立middleware目錄。
內建中介軟體例子
上面的例子,我們實現了一個名叫“M1”的內建中介軟體,該中介軟體先輸出了“>> M1 in >> ”,然後通過next()方法交到下一中介軟體處理,等到處理完成後,再執行後置處理(輸出<< M1 out >>)
應用自定義中介軟體應用開發者要實現自定義中介軟體也很簡單,與內建中介軟體類似,需繼承“PHPec\\Middleware”,在應用目錄下的middleware儲存自定義中介軟體。下面建立一個自定義中介軟體:
應用自定義中介軟體例子
使用中介軟體中介軟體準備好了,接下來看怎麼使用,對於應用開發者來說,只需要先在入口檔案使用App::use方法來加入要使用的中介軟體即可。
// 應用入口檔案<?php//filename: application/src/index.php// 以下省略不相關內容$app = Bootstrap::run();$app -> use('M1', 'M2');$app -> use('M3');$app -> run(); ?>程式碼說明:
可以一次加入多個,有序
如果自定義中介軟體與內建中介軟體重名,則優先使用自定義的,即應用開發者可以用自定義同名中介軟體的方式來覆蓋內建中介軟體。
排程方式中介軟體由框架的APP物件負責新增和排程
中介軟體排程
程式碼說明:
_add()方法負責將中介軟體新增到佇列中(使用mTail指向隊尾,每次新增前,將上次隊尾的$next指向新加入的中介軟體,並移動隊尾到新加入的中介軟體)
因為use為保留關鍵字,不能用於方法名,但習慣上經常會使用use來加入中介軟體,所以使用魔術方法__call()來攔截use()方法,並轉發給_add()處理
run為應用正式開始執行的入口,直接呼叫隊頭的handle()方法即可,再在各中介軟體的handle中呼叫next()方法排程下一中介軟體,直到沒有下一個再逐一回溯,達到洋蔥模型的效果。
例項了解了中介軟體如何實現後,下面我們來實現一些常見的中介軟體。
IPKeeper (IP限制)可以根據請求IP來判斷是否放行,支援白名單和黑名單。
IP限制中介軟體
程式碼說明:
通過配置引數“ip.allow”和“ip.deny”指定ip的白名單和黑名單,然後獲得請求的來源IP,根據是否在白名單或黑名單中來判斷是否有權訪問如果未獲授權,記錄日誌;設定錯誤響應然後返回(不執行$this -> next(),表示跳過餘下中介軟體)。常量CODE_ACCESS_DENY為一通用常量,可使用一個consts.php檔案來引入框架用到的通用常量。MethodKeeper (請求方法限制)與IPKeeper類似,MethodKeeper是根據請求的方法(method)來判斷是否放行
SlowLog (超時請求日誌)我們知道,MySQL裡有slow query log,在這裡,我們也實現一個類似功能的中介軟體。
SlowLog中介軟體
程式碼說明:
前置處理,先記錄請求到達的時間,然後交到下一中介軟體。
在處理完成回到該中介軟體時,繼續進入到後置處理。
通過進入到後置處理的時間減去前置處理記錄的時間點,計算出所耗時間,並與配置引數中的超時時間設定比較,當執行時間大於設定的timeout時,記錄請求引數和所耗時間。
小結本節講解了WEB中介軟體的相關知識,包括中介軟體的定義和作用、實現方式以及使用方法,同時也實現了幾個比較簡單和通用的中介軟體例子。
下一篇,我們繼續探討一下文中提到但未實現的路由中介軟體和Dispatcher中介軟體。