php hyperf框架的依赖注入的注解语法报错
如果我们用到了hyperf框架中的依赖注入的注解语法,但是会出现框架在属性注入阶段无法获取到容器实例的报错,例如:
一:出现的报错:
[ERROR] Hyperf\Context\ApplicationContext::getContainer(): Return value must be of type Psr\Container\ContainerInterface, null returned[27] in /opt/www/vendor/hyperf/context/src/ApplicationContext.php
[ERROR] #0 /opt/www/vendor/hyperf/di/src/Aop/RegisterInjectPropertyHandler.php(39): Hyperf\Context\ApplicationContext::getContainer()
#1 /opt/www/vendor/hyperf/di/src/Aop/PropertyHandlerTrait.php(90): Hyperf\Di\Aop\RegisterInjectPropertyHandler::Hyperf\Di\Aop\{closure}()
#2 /opt/www/vendor/hyperf/di/src/Aop/PropertyHandlerTrait.php(31): App\Controller\Client\UserController->__handle()
#3 /opt/www/runtime/container/proxy/App_Controller_Client_UserController.proxy.php(23): App\Controller\Client\UserController->__handlePropertyHandler()
#4 /opt/www/vendor/hyperf/di/src/Resolver/ObjectResolver.php(85): App\Controller\Client\UserController->__construct()
#5 /opt/www/vendor/hyperf/di/src/Resolver/ObjectResolver.php(52): Hyperf\Di\Resolver\ObjectResolver->createInstance()
#6 /opt/www/vendor/hyperf/di/src/Resolver/ResolverDispatcher.php(51): Hyperf\Di\Resolver\ObjectResolver->resolve()
#7 /opt/www/vendor/hyperf/di/src/Resolver/DepthGuard.php(68): Hyperf\Di\Resolver\ResolverDispatcher->Hyperf\Di\Resolver\{closure}()
#8 /opt/www/vendor/hyperf/di/src/Resolver/ResolverDispatcher.php(49): Hyperf\Di\Resolver\DepthGuard->call()
#9 /opt/www/vendor/hyperf/di/src/Container.php(159): Hyperf\Di\Resolver\ResolverDispatcher->resolve()
#10 /opt/www/vendor/hyperf/di/src/Container.php(62): Hyperf\Di\Container->resolveDefinition()
#11 /opt/www/vendor/hyperf/di/src/Container.php(102): Hyperf\Di\Container->make()
#12 /opt/www/vendor/hyperf/http-server/src/CoreMiddleware.php(142): Hyperf\Di\Container->get()
#13 /opt/www/vendor/hyperf/http-server/src/CoreMiddleware.php(97): Hyperf\HttpServer\CoreMiddleware->handleFound()
#14 /opt/www/vendor/hyperf/dispatcher/src/AbstractRequestHandler.php(45): Hyperf\HttpServer\CoreMiddleware->process()
#15 /opt/www/vendor/hyperf/dispatcher/src/HttpRequestHandler.php(27): Hyperf\Dispatcher\AbstractRequestHandler->handleRequest()
#16 /opt/www/vendor/hyperf/validation/src/Middleware/ValidationMiddleware.php(84): Hyperf\Dispatcher\HttpRequestHandler->handle()
#17 /opt/www/vendor/hyperf/dispatcher/src/AbstractRequestHandler.php(45): Hyperf\Validation\Middleware\ValidationMiddleware->process()
#18 /opt/www/vendor/hyperf/dispatcher/src/HttpRequestHandler.php(27): Hyperf\Dispatcher\AbstractRequestHandler->handleRequest()
#19 /opt/www/vendor/hyperf/dispatcher/src/HttpDispatcher.php(35): Hyperf\Dispatcher\HttpRequestHandler->handle()
#20 /opt/www/vendor/hyperf/http-server/src/Server.php(112): Hyperf\Dispatcher\HttpDispatcher->dispatch()
#21 [internal function]: Hyperf\HttpServer\Server->onRequest()
#22 {main}
二:问题分析:
-
错误根源:
ApplicationContext::getContainer()返回了null -
发生时机:在属性注入阶段(
RegisterInjectPropertyHandler)访问容器时 -
根本原因:容器尚未准备好或上下文未正确初始化
三:解决方案:
方案1:检查容器初始化(推荐)
我们使用的依赖注入的注解语法:
namespace App\Service;
use App\Model\User;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Redis\Redis;
class UserService
{
#[Inject]
private Redis $redis;
}
在 config/container.php 或项目入口确保容器正确初始化:
// config/container.php
use Hyperf\Context\ApplicationContext;
use Hyperf\Di\Container;
use Hyperf\Di\Definition\DefinitionSourceFactory;
$container = new Container((new DefinitionSourceFactory())());
ApplicationContext::setContainer($container);//关键
return $container;
方案2:使用构造函数注入
构造函数注入在对象创建时执行,此时容器已经初始化:
class UserController extends AbstractController
{
private Redis $redis;
public function __construct(Redis $redis)
{
$this->redis = $redis;
}
}
目前方案1使用的最多,添加一行关键代码即可
本文来自博客园,作者:Carvers,转载请注明原文链接:https://www.cnblogs.com/carver/articles/19592093

浙公网安备 33010602011771号