这里详细描述问题
我在使用依赖注入的过程发现,我如果在构造方法中注入了request,会导致在使用的时候一些方法调用会有问题,比如getRemoteIp()、getRealIp()之类的
// 注释的方式如下,
// 已经在dependence.php添加了\support\Request::class => function () {return request();}
use support\Request;
class RequestService
{
public function __construct(public Request $req){}
// 第一次通过接口调用这个方法的话,有值,但是如果通过接口调用的话,会报错
public function test(){
return dd($this->req->getRemoteIp());
}
}
// 其中进程数设置为1,控制器复用也默认关闭,接口请求为post,测试发现第一次会返回正常的ip,当再次调用则依旧显示报错
// 控制器
namespace app\controller;
use support\Request;
class IndexController
{
public function __construct(public Request $req){}
public function index(Request $request)
{
return json($this->req->getRemoteIp());
}
}
// container.php
$builder = new \DI\ContainerBuilder();
$builder->addDefinitions(config('dependence', []));
$builder->useAutowiring(true);
$builder->useAnnotations(true);
return $builder->build();
// dependence.php
return [
\support\Request::class => function () {
return \request();
},
];
Error: Call to a member function getRemoteIp() on null in /work/codingItems/webman-api/vendor/workerman/webman-framework/src/Http/Request.php:178
Stack trace:
#0 /work/codingItems/webman-api/vendor/workerman/webman-framework/src/Http/Request.php(215): Webman\Http\Request->getRemoteIp()
#1 /work/codingItems/webman-api/app/common/api/request/RequestService.php(35): Webman\Http\Request->getRealIp()
#2 /work/codingItems/webman-api/app/admin/controller/PersonalController.php(18): app\common\api\request\RequestService->checkGetKeys()
#3 /work/codingItems/webman-api/vendor/workerman/webman-framework/src/App.php(325): app\admin\controller\PersonalController->login()
#4 /work/codingItems/webman-api/vendor/workerman/webman-framework/src/App.php(141): Webman\App::Webman\{closure}()
#5 /work/codingItems/webman-api/vendor/workerman/workerman/Connection/TcpConnection.php(646): Webman\App->onMessage()
#6 /work/codingItems/webman-api/vendor/workerman/workerman/Events/Select.php(311): Workerman\Connection\TcpConnection->baseRead()
#7 /work/codingItems/webman-api/vendor/workerman/workerman/Worker.php(1635): Workerman\Events\Select->loop()
#8 /work/codingItems/webman-api/vendor/workerman/workerman/Worker.php(1426): Workerman\Worker::forkOneWorkerForLinux()
#9 /work/codingItems/webman-api/vendor/workerman/workerman/Worker.php(1400): Workerman\Worker::forkWorkersForLinux()
#10 /work/codingItems/webman-api/vendor/workerman/workerman/Worker.php(560): Workerman\Worker::forkWorkers()
#11 /work/codingItems/webman-api/vendor/workerman/webman-framework/src/support/App.php(131): Workerman\Worker::runAll()
#12 /work/codingItems/webman-api/start.php(4): support\App::run()
#13 {main} [] []
workerman/webman-framework:v1.5.11
系统环境为wsl2中的Ubuntu20.04
php版本为8.1.7
你的RequestService是怎么初始化的
通过接口,首先是去注册了\app\common\api\interfaces\RequestInterface::class => function (ContainerInterface $c) {
return $c->make(\app\common\api\request\RequestService::class);
},然后编写class RequestService implements RequestInterface,其中RequestService中就只和上面写的一样,只有public function __construct(public Request $req){}这一个地方初始化,最后控制器里面public function __construct(public RequestInterface $req),利用$this->req->test()
php用的是8.1,以及我发现如果把RequestService中的public function __construct(public Request $req){}删除,然后服务内的之前的依赖注入的req参数用帮助函数request(),倒是不会出现这个问题
看现象是RequestService示例持久化到内存了,你每次使用的都是第一次实例化的RequestService。里面的request对象是过期的,连接已经断开,connection为null,无法获取getRemoteIp
大大,针对于这种情况有什么解决方案嘛?还是说就老老实实用帮助方法就好了,不去对于Request做非控制器外的注入
需要看下是不是复用了RequestService实例。进程数设置为1,然后RequestService的构造函数里输出日志。
看下是否是每次请求都初始化新的RequestService实例。
如果RequestService实例被复用了,需要看下哪里缓存了RequestService实例,比如是否开了resue_controller复用控制器导致。
我重新初始化创建了一个webman项目,然后通过直接在初始化的IndexController示例中通过public function __construct(public Request $req){}进行依赖注入,以及在public function index(){return json($this->req->getRemoteIp());}调用,发现还是会存在第一次有值,再次调用的话就报错Call to a member function getRemoteIp() on null。但是这种情况好像只存在于post请求,get请求是正常的。其中控制器复用是默认关闭的,进程数我也设置为'count' => 1了
项目打包发到 walkor@workerman.net 我看下
大大,发送过去了~