在webman中,在一个进程中,静态变量、(单例)都是所有请求中共享使用,那么有没有可以做到在仅仅在一个请求中,某个(单例)类可以在这个请求业务任意一个地方可以使用,不需要重复实例化呢(不同请求之间不能互相使用),这个类在这个请求结束后自动释放?
举个例子
1、目前log类实例化后(同一个通道),在一个进程后就只有一个日志类(全局日志类),但我想在每次写日志时都要附带上额外的信息(本次请求的信息【包括我自定义的信息】或者用户个人信息),要是我每次写入的时候就加上额外信息(如:Log::info($user->username.'log test')),那我觉得有点麻烦,所以我继承并改写了Log类,新增一个方法可以做到每次实例化时都时一个新类,那么这个类就只为本次请求服务,但问题来了,我如何可以在本次请求中任意协程、任意类中使用他呢,不需要每次都实例化一个新类,就像传统web那样的单例模式
上个问题不是有说用Context么
也试过这个方法,尝试在中间件中使用Context,然后在控制器中使用Context获取,但发现不行(我用了协程的),后来在手册的某个页面看到$request(support\Request;)变量,就想到了把本次请求的所有全局变量都放到这里,比如$request->userlog=Log::diyChannel('log2')【我新增的方法,每次都实例化新的实例】,然后在其他地方用,其余的办法就想不到了
Context 可以实现 90% 的需求。
但是
Swoole
会复用协程,而且子协程有独立的上下文,跟阁下的需求相去甚远。最简单的办法实手动管理上下文,让请求跟上下文绑定,而不是上下文跟请求绑定。
你需要重写创建协程的方法, 在创建协程的时候 把request 的信息放到 context 里面
你想要把数据放在本次请求里面,实际上你的问题已经给了你答案,就是将数据放到request对象里面即可。如何控制加载这个数据的时机,可以看一下中间件章节的文档,如果是请求开始就需要加入就在全局中间件里面加载数据,如果是用户信息的数据应该是在验证token或者session的中间件里面增加数据加载逻辑