如今經常使用框架都有實現中間件,那麼中間件是如何實現的呢?php
這裏實現的方法是經過閉包,固然也能夠經過AST方法實現,將源碼解析爲AST樹,在須要切入的地方插入代碼,而後還原爲代碼,這種實現方法過於複雜,通常只有須要實現複雜的切入時才須要。shell
class A{ public function run($a){ echo "A:".$a; } } class B{ public function run($name,$handler){ var_dump('B'); $log= $handler($name); var_dump('B-'); return $log; } } class C{ public function run($name,$handler){ var_dump('C'); $log= $handler($name); var_dump('C-'); return $log; } } $aa = function($a){ return (new A)->run($a); }; $stack[]=B::class; $stack[]=C::class; function middleware($handler, $stack) { foreach (array_reverse($stack) as $key => $middleware) { $log = function($handler) use($middleware){ return function($name) use ($handler,$middleware) { $class = new $middleware(); return $class->run($name,$handler); }; }; $handler=$log($handler); } return $handler; } $run = middleware($aa,$stack); $run('asd');
執行上述代碼,打印以下內容閉包
string(1) "B" string(1) "C" A:asdstring(2) "C-" string(2) "B-"