laravel/lumen 接口执行时间记录以及前后置中间件terminate的使用
2020-04-24 07:33
841 查看
routemidlleware 不支持 terminate 这是基于什么考虑的。不管 laravel 还是 lumen 只有 global middleware 才会去 call terminate 而 routemiddleware 却不会
中间件文件都放在app/http/Middleware文件夹中,可以根据ExampleMiddleware.php进行创建
前置中间件
[code]namespace App\Http\Middleware; use Closure; define('START', microtime(true)); class BeforeMiddleware { //第三个参数为额外传参 public function handle($request, Closure $next) { //前置中间件,在执行路由定义指定的操作前做你想做的事情 return $next($request); } }
后置中间件
[code]<?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() 调用参数数组中。
[code]$app->middleware([ App\Http\Middleware\Authenticate::class, ]);
Terminable中间件
有些时候中间件需要在 HTTP 响应被发送到浏览器之后才运行,例如,「session」中间件存储的 session 数据是在响应被发送到浏览器之后才进行写入的。想要做到这一点,你需要定义中间件为「terminable」。
[code]<?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 会从 服务容器 解析一个全新的中间件实例。
如果你希望在
handle及
terminate方法被调用时使用一致的中间件实例,只需在容器中使用容器的
singleton方法注册中间件。
[code]$app->singleton( App\Http\Middleware\terminable::class );
如果上面的代码个别接口执行不到terminate的话(这里是坑,至今未找到原因),你可以尝试以下方法
在底层控制器中的的构造方法__construct中注册函数register_shutdown_function
注册一个
callback,它会在脚本执行完成或者 exit() 后被调用。
可以多次调用 register_shutdown_function() ,这些被注册的回调会按照他们注册时的顺序被依次调用。 如果你在注册的方法内部调用 exit(), 那么所有处理会被中止,并且其他注册的中止回调也不会再被调用
[code]public function __construct() { register_shutdown_function(array($this, 'test')); } public function test() { //成功完成后置中间件里的内容 // TODO 切记 请勿die/exit }
以上是本人总结的方法和遇到的坑,如果有更好的方案,欢迎提出
- 点赞 1
- 收藏
- 分享
- 文章举报
相关文章推荐
- 记录接口执行时间的中间件
- 使用Spring3.0的AOP结合log4j实现接口方法执行时间记录
- 使用Spring的AOP实现接口方法执行时间记录
- 启用mysql日志记录执行过的sql并且开启慢查询记录所有超过慢查询时间的SQL以及未使用索引SQL
- django 中间件记录所有请求及请求执行时间
- controller中使用@RequestBody,Java如何传递json对象访问接口,以及对象中的时间类型
- 【HAVENT原创】使用 Spring Boot 的 AOP 全局记录执行时间日志
- 查看当前语言环境 以及 记录命令执行时间
- 使用aop记录数据库操作的执行时间
- Windows下安装Composer 以及使用Composer安装laravel和lumen指定版本
- 使用动态代理记录方法执行的时间
- SpringAop在项目中的一些巧妙使用(一)---方法执行时间记录
- 五种简单Dialog的使用,以及时间,日期Dialog中onDateSet,onTimeSet被执行两次的Bug
- 【转载】使用动态代理记录方法执行的时间
- Spring AOP日志记录接口请求参数,执行时间
- Linux history 命令记录加执行时间戳以及记录到日志
- 使用动态代理记录方法执行的时间
- 如何管理和记录 SSIS 各个 Task 的开始执行时间和结束时间以及 Task 中添加|删除|修改的记录数
- php使用FFmpeg接口获取视频的播放时长、码率、缩略图以及创建时间
- 让history记录命令的历史执行时间