在使用webman做项目时发现一个关于中间件向控制器传参数的问题,根据文档的提示(通过给$request对象添加属性的方式向控制器传参),在中间件中我设置了一个请求id(request_id)(为了可以对比,我使用了Context储存了request_id),然后在控制器中读取它,我特意在中间件穿越前输出到日志,并在控制器上使用Context读取其值,与$request->request_id作比较并写入日志。
备注:我开启协程Workerman\Events\Swoole::class、1进程下
我通过linux的ab命令来并发10次请求,并在在下面日志中我发现个别现象:
格式:Context的值【控制器读取数据】:$request->request_id的值
1、[2025-04-01 15:21:21] log2.INFO: 0GNY-68VM190J-9LBQIC2C-6F26控制器读取数据:0GNY-68VM190J-9LBQIC2C-6F26 [] []
2、[2025-04-01 15:21:21] log2.INFO: UUO1-LPHP5MEX-YXWUYKLB-CVBQ控制器读取数据:YDD1-O83MEIWR-V7O4NYKJ-7S38 [] []
3、[2025-04-01 15:21:21] log2.INFO: 4LB9-UQRMO1BE-0NWGQZ6R-IPJ1控制器读取数据: [] []
其中【1】就是我想要的结果,$request->request_id跟Context的request_id一致
其中【2、3】就是我想不到为何会出现这样结果,【2】$request->request_id跟Context的request_id不一致,【3】$request->request_id为空
<?php
namespace app\middleware;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
use support\Context;
use support\Log;
class GolbalRequest implements MiddlewareInterface{
public function process(Request $request, callable $handler) : Response
{
$request_id = generateRequestId();
$request->request_id=$request_id;
Context::set('request_id',$request_id);
$log=Log::Channel('log2');
$log->useLoggingLoopDetection(false);
$log->info('请求开始,获取request_id:'.$request_id);
$response = $handler($request); // 继续向洋葱芯穿越,直至执行控制器得到响应
return $response;
}
}
?>
<?php
namespace app\bot\controller;
use support\Request;
class IndexController
{
public function index(Request $request)
{
$request_id=Context::get('request_id');
$log=Log::Channel('log2');
$log->info($request_id.'控制器读取数据:'.$request->request_id);
}
}
[2025-04-01 15:21:20] log2.INFO: 请求开始,获取request_id:0GNY-68VM190J-9LBQIC2C-6F26 [] []
[2025-04-01 15:21:21] log2.INFO: 0GNY-68VM190J-9LBQIC2C-6F26控制器读取数据:0GNY-68VM190J-9LBQIC2C-6F26 [] []
[2025-04-01 15:21:21] log2.INFO: 请求开始,获取request_id:UUO1-LPHP5MEX-YXWUYKLB-CVBQ [] []
[2025-04-01 15:21:21] log2.INFO: 请求开始,获取request_id:UIX9-JG2U37UN-WPAJ86VD-X3SO [] []
[2025-04-01 15:21:21] log2.INFO: 请求开始,获取request_id:4LB9-UQRMO1BE-0NWGQZ 6R-IPJ1 [] []
[2025-04-01 15:21:21] log2.INFO: 请求开始,获取request_id:YDD1-O83MEIWR-V7O4NYKJ-7S38 [] []
[2025-04-01 15:21:21] log2.INFO: UUO1-LPHP5MEX-YXWUYKLB-CVBQ控制器读取数据:YDD1-O83MEIWR-V7O4NYKJ-7S38 [] []
[2025-04-01 15:21:21] log2.INFO: UIX9-JG2U37UN-WPAJ86VD-X3SO控制器读取数据:YDD1-O83MEIWR-V7O4NYKJ-7S38 [] []
[2025-04-01 15:21:21] log2.INFO: 请求开始,获取request_id:35GW-YOAICD9R-7MVSV6EK-E7WN [] []
[2025-04-01 15:21:21] log2.INFO: 4LB9-UQRMO1BE-0NWGQZ6R-IPJ1控制器读取数据: [] []
[2025-04-01 15:21:21] log2.INFO: 请求开始,获取request_id:7U3D-TT0Q1GKC-9K31DU9X-SPDO [] []
[2025-04-01 15:21:21] log2.INFO: YDD1-O83MEIWR-V7O4NYKJ-7S38控制器读取数据: [] []
[2025-04-01 15:21:21] log2.INFO: 请求开始,获取request_id:K64C-U12411DA-JX4SXOEH-X7M5 [] []
[2025-04-01 15:21:21] log2.INFO: 35GW-YOAICD9R-7MVSV6EK-E7WN控制器读取数据: [] []
[2025-04-01 15:21:21] log2.INFO: 7U3D-TT0Q1GKC-9K31DU9X-SPDO控制器读取数据:7U3D-TT0Q1GKC-9K31DU9X-SPDO [] []
[2025-04-01 15:21:21] log2.INFO: K64C-U12411DA-JX4SXOEH-X7M5控制器读取数据:K64C-U12411DA-JX4SXOEH-X7M5 [] []
[2025-04-01 15:21:21] log2.INFO: 请求开始,获取request_id:79K2-1JG1EG36-0J0YOMZ1-VYJ9 [] []
[2025-04-01 15:21:21] log2.INFO: 79K2-1JG1EG36-0J0YOMZ1-VYJ9控制器读取数据:79K2-1JG1EG36-0J0YOMZ1-VYJ9 [] []
[2025-04-01 15:21:21] log2.INFO: 请求开始,获取request_id:9IO7-FT6CVZXQ-0Z3PRCGX-N9JM [] []
[2025-04-01 15:21:21] log2.INFO: 9IO7-FT6CVZXQ-0Z3PRCGX-N9JM控制器读取数据:9IO7-FT6CVZXQ-0Z3PRCGX-N9JM [] []
linux系统
composer.json参数:
"php": ">=8.1",
"workerman/webman-framework": "^2.1",
"monolog/monolog": "^2.0",
除了上面问题,关于Request类我最近有一个疑问,就是开启协程后,此时的Request类是是不是本次请求的局部变量,还是在一个进程中的全局变量?并发的时候,Request类的属性会不会被其他(同进程)请求所覆盖?文档好似没有关于这方面的描述,有没有大佬解释一下?
1.约等于全局
2.只要不是直接修改$request就不会覆盖,协程内上下文传递请用Context
试下dev版本是否有问题