routemidlleware 不支持 terminate 這是基於什麼考慮的。無論 laravel 仍是 lumen 只有 global middleware 纔會去 call terminate 而 routemiddleware 卻不會php
中間件文件都放在app/http/Middleware文件夾中,能夠根據ExampleMiddleware.php進行建立laravel
namespace App\Http\Middleware;
use Closure;
define('START', microtime(true));
class BeforeMiddleware
{
//第三個參數爲額外傳參
public function handle($request, Closure $next)
{
//前置中間件,在執行路由定義指定的操做前作你想作的事情
return $next($request);
}
}複製代碼
<?php
namespace App\Http\Middleware;
use Closure;
class AfterMiddleware
{
//第三個參數爲額外傳參
public function handle($request, Closure $next)
{
$response = $next($request);
//後置中間件,在執行完路由定義指定的操做後(也就是響應前)作你想作的事情
echo 1;
return $response;
}
} 複製代碼
每一個 HTTP 請求都通過一箇中間件,只要將中間件的類加入到 bootstrap/app.php 的 $app->middleware() 調用參數數組中。bootstrap
$app->middleware([
App\Http\Middleware\Authenticate::class,
]);
複製代碼
有些時候中間件須要在 HTTP 響應被髮送到瀏覽器以後才運行,例如,「session」中間件存儲的 session 數據是在響應被髮送到瀏覽器以後才進行寫入的。想要作到這一點,你須要定義中間件爲「terminable」。 數組
<?php
namespace Illuminate\Session\Middleware;
use Closure;
use Illuminate\Support\Facades\Log;
class StartSession
{
public function handle($request, Closure $next)
{
// 開始
Log::info($_SERVER['REQUEST_URI'].'開始'.START.'微秒');
return $next($request);
}
public function terminate($request, $response)
{
//結束
$end = microtime(true);
Log::info($_SERVER['REQUEST_URI'].'結束'.$end.'微秒');
$diff = ($end-START) * 1000;
if ($diff >= 1500) {
Log::info("接口{".$_SERVER['REQUEST_URI']."}從請求開始到結束相差{$diff}毫秒");
}
}
}複製代碼
terminate
方法必須接收請求及響應。一旦定義了 terminable 中間件,你便須要將它增長到 bootstrap/app.php
文件的全局中間件清單列表中。瀏覽器
當在你的中間件調用 terminate
方法時,Lumen 會從 服務容器 解析一個全新的中間件實例。bash
若是你但願在 handle
及 terminate
方法被調用時使用一致的中間件實例,只需在容器中使用容器的 singleton
方法註冊中間件。session
$app->singleton(
App\Http\Middleware\terminable::class
);
複製代碼
若是上面的代碼個別接口執行不到terminate的話(這裏是坑,至今未找到緣由),你能夠嘗試如下方法app
在底層控制器中的的構造方法__construct中註冊函數register_shutdown_function函數
註冊一個 callback
,它會在腳本執行完成或者 exit() 後被調用。ui
能夠屢次調用 register_shutdown_function() ,這些被註冊的回調會按照他們註冊時的順序被依次調用。 若是你在註冊的方法內部調用 exit(), 那麼全部處理會被停止,而且其餘註冊的停止回調也不會再被調用
public function __construct()
{
register_shutdown_function(array($this, 'test'));
}
public function test()
{
//成功完成後置中間件裏的內容
// TODO 切記 請勿die/exit
}複製代碼