PHP中间件(middleware)解析
来源:互联网 发布:简单 三维建模软件 编辑:程序博客网 时间:2024/05/16 14:02
笔者在研读guzzlehttp
源码时,对中间件的使用研究了一翻,在此纪录学习笔记。
我的理解
在执行主要逻辑时,完成一些附带的逻辑,可以分为前置和后置中间件。附带的逻辑往往带有条件判断,比如验证是否有权限,判断配置信息从而做出相应操作。目的是使各个业务逻辑更清晰、独立、可拆卸。
举例
// 主要逻辑$meet = function($name){ echo "nice to meet you, $name \n";};// 前置中间件$hello = function($handler){ return function($name)use($handler){ echo "hello ".$name.", may I have your name\n"; $name = 'Lucy'; return $handler($name); };};// 前置中间件$weather = function($handler){ return function($name)use($handler){ echo 'what a day'."\n"; return $handler($name); // weather_return_handler行 };};// 后置中间件$dinner = function($handler){ return function($name)use($handler){ $return = $handler($name); $name = 'Lucy'; echo "OK, $name. Will you have dinner with me?\n"; return $return; };};// 中间件栈$stack = [];// 打包function prepare($handler, $stack){ foreach(array_reverse($stack) as $key => $fn){ // echo $key; 记为echo_key行 $handler = $fn($handler); // 记为iterator行 } return $handler;}// 入栈$stack['dinner'] = $dinner;$stack['weather'] = $weather;$stack['hello'] = $hello;// 把所有逻辑打包成一个闭包(closure)$run = prepare($meet, $stack);$run('beauty'); // 记为run_prepare/* 执行结果:what a dayhello beauty, may I have your namenice to meet you, Lucy OK, Lucy. Will you have dinner with me?*/
编写规范
中间件要要满足一定的规范:总是返回一个闭包,闭包中总是传入相同的参数(由主要逻辑决定), 闭包总是返回句柄(handler)的执行结果;
如果中间件的逻辑在返回句柄return $handler($name)
前完成,就是前置中间件,否则为后置。这只是一个代码规范,你完全可以在一个中间件中的任何位置写逻辑代码,只要在最后正确返回。
打包程序
中间件的执行顺序是由打包函数(prepare)决定,这里是先入栈先执行,比如weather比hello先执行。
打包函数是一个这里有趣的地方。如果把prepare函数中的echo_key行 注释打开,会发现打包顺序是hello, weather, dinner。
所以,返回的闭包实际上相当于:
$closure = $dinner($weather($hello($meet))); // 记为make_closure行$closure('beauty'); // 记为run_closure
困惑的地方在于,为什么weather的执行顺序在hello前。常规的函数如A(B(C('hehe')))
, 执行顺序应该是C,B,A。
因为中间件是一个闭包,而且返回一个闭包(满屏尽是闭包),意味着一个中件间要运行两次。外层闭包在打包的时候执行,也就是iterator行 或者 make_closure行,同时决定里层的执行顺序。里层闭包在调用时执行, run_prepare行或run_closure行。
表达式$hello($meet)
返回的是$hello
的里层闭包而不是句柄,因为里层未执行,所以hello beauty
不会出现。也就是说,$weather
的形参$handler
对应的实参就是$hello
的里层闭包。当程序运行到weather_return_handler
行时,$hello
的里层闭包才真正执行,这时$weather
的逻辑已经执行完了。
打包程序的作用可以概括为执行当前中间件的外层闭包,得到里层闭包作为参数,再传给下一个中间件的外层闭包,直至迭代结束。
- PHP中间件(middleware)解析
- PHP中间件(middleware)解析
- 中间件 (Middleware)
- redux的中间件(middleware)
- 中间件 Middleware
- 中间件 Middleware
- Middleware 中间件
- laravel(七)-中间件(Middleware)
- Koa中间件(middleware)实现探索
- Django框架全面讲解 -- 中间件(MiddleWare)
- ASP.NET Core中间件(Middleware)实现WCF SOAP服务端解析
- 关于中间件(MiddleWare)
- Middleware【中间件】简介
- 中间件(middleware)技术概括
- Django 中间件 Middleware
- .NET Core 中间件MiddleWare
- Spider 中间件(Middleware)
- Laravel Middleware 中间件
- 远程控制
- Error reading from database: java.sql.SQLException: Streaming result set com.mysql.jdbc.RowDataDyna
- Cubietruck---7. fex2bin源码简要分析(未完成)
- 离开hover的响应事件
- 流量卡文档
- PHP中间件(middleware)解析
- Linux编辑器vi的使用笔记
- uboot启动内核的实现
- Cubietruck---8. u-boot及boot.img简略分析
- 修改 eclipse 文件编码格式
- 关于预防流氓软件入侵的一点小心得
- AndroidManifest.xml中的minSdkVersion、targetSdkVersion、maxSdkVersion和project.properties中target API lev
- iOS Xcode项目在SVN更新后无法打开解决办法
- RTP协议全解(H264码流和PS流)