ワンクリックで
hyperf-container
Hyperf 依赖注入容器使用指南,包括服务注册、依赖获取、自动注入等基础概念。使用当处理 Hyperf 项目中的依赖注入、Container 操作、DI 配置或服务管理时。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Hyperf 依赖注入容器使用指南,包括服务注册、依赖获取、自动注入等基础概念。使用当处理 Hyperf 项目中的依赖注入、Container 操作、DI 配置或服务管理时。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
Hyperf 版本感知开发指南。当检测到项目使用 Hyperf 3.x 时,自动应用对应版本的编码规范:3.1+ 必须使用 `\Hyperf\Support\env()` 或 `use function Hyperf\Support\env` 而非全局 `env()`;3.2+ 需使用新的 Logger/Cache 配置结构。适用于代码生成、配置编写、问题诊断等所有 Hyperf 开发场景。
w7corp/easywechat 微信开发 SDK 使用指南,涵盖公众号、小程序、企业微信、微信支付等平台接口开发。包含 Hyperf 框架集成、消息处理、OAuth 授权、支付流程等。使用当开发微信相关功能、处理微信回调、实现微信登录或支付时。
SOC 職業分類に基づく
| name | hyperf-container |
| description | Hyperf 依赖注入容器使用指南,包括服务注册、依赖获取、自动注入等基础概念。使用当处理 Hyperf 项目中的依赖注入、Container 操作、DI 配置或服务管理时。 |
Hyperf 基于 PSR-11 标准实现依赖注入容器,是框架的核心组件。
use Hyperf\Utils\ApplicationContext;
// 方式一:通过 ApplicationContext(推荐)
$container = ApplicationContext::getContainer();
// 方式二:在 Controller/Service 中直接注入
public function __construct(
private \Psr\Container\ContainerInterface $container
) {}
如果项目中定义了全局 di() 函数,可以简化容器访问:
检测 di() 函数是否存在:
检查项目中是否有类似以下的全局函数定义(通常在 app/Kernel/Functions.php):
use Hyperf\Context\ApplicationContext;
function di(?string $id = null)
{
$container = ApplicationContext::getContainer();
if ($id) {
return $container->get($id);
}
return $container;
}
使用方式:
// 获取容器实例
$container = di();
// 直接获取服务
$userService = di(App\Service\UserService::class);
何时建议添加 di() 函数:
ApplicationContext::getContainer()->get(...)注意: di() 是可选的便利函数,不是 Hyperf 内置功能,需手动定义。
// 直接获取实例
$userService = $container->get(App\Service\UserService::class);
// 判断服务是否存在
if ($container->has(App\Service\UserService::class)) {
$userService = $container->get(App\Service\UserService::class);
}
namespace App\Controller;
use App\Service\UserService;
use Hyperf\HttpServer\Annotation\AutoController;
#[AutoController]
class UserController
{
public function __construct(
private UserService $userService
) {}
public function index()
{
// 直接使用 $this->userService
return $this->userService->list();
}
}
优势:
Hyperf 会自动扫描 App 命名空间下的类并注册到容器,无需手动配置。
// app/Service/UserService.php
namespace App\Service;
class UserService
{
public function list(): array
{
return [];
}
}
用于第三方组件或需要自定义配置的服务:
// config/autoload/dependencies.php
return [
// 绑定接口到实现
App\Repository\UserRepositoryInterface::class => App\Repository\UserRepository::class,
// 单例模式(默认就是单例)
App\Service\CacheService::class => \Hyperf\Di\Annotation\Singleton::class,
];
对于需要手动注册的服务,应创建 Listener 监听 BootApplication 事件:
步骤 1: 创建 Listener
namespace App\Listener;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Event\Annotation\Listener;
use Hyperf\Framework\Event\BootApplication;
use Psr\Container\ContainerInterface;
use Psr\EventDispatcher\ListenerProviderInterface;
#[Listener]
class ServiceRegisterListener implements ListenerProviderInterface
{
public function __construct(
private ContainerInterface $container
) {}
public function listen(): array
{
return [
BootApplication::class,
];
}
public function process(object $event): void
{
// 注册自定义服务
$this->container->set(
'custom.service',
new \App\Service\CustomService(
$this->container->get(ConfigInterface::class)
)
);
}
}
关键点:
Hyperf\Framework\Event\BootApplication 事件#[Listener] 注解让 Hyperf 自动发现process() 方法中执行服务注册逻辑当需要动态创建对象或控制实例化过程时,使用 Factory:
步骤 1: 定义接口
namespace App\Service;
interface OrderServiceInterface
{
public function create(array $data): int;
public function findById(int $id): ?array;
}
步骤 2: 实现接口
namespace App\Service;
use App\Repository\OrderRepository;
use Hyperf\DbConnection\Db;
class OrderService implements OrderServiceInterface
{
public function __construct(
private OrderRepository $orderRepository,
private int $timeout,
private Db $db
) {}
public function create(array $data): int
{
return $this->orderRepository->insert($data);
}
public function findById(int $id): ?array
{
return $this->orderRepository->find($id);
}
}
步骤 3: 创建 Factory 类
namespace App\Factory;
use App\Service\OrderService;
use App\Service\OrderServiceInterface;
use Hyperf\Contract\ConfigInterface;
use Hyperf\DbConnection\Db;
use Psr\Container\ContainerInterface;
class OrderServiceFactory
{
public function __invoke(ContainerInterface $container): OrderServiceInterface
{
// 可以在此处进行复杂的初始化逻辑
$config = $container->get(ConfigInterface::class);
$db = $container->get(Db::class);
return new OrderService(
$container->get(\App\Repository\OrderRepository::class),
$config->get('app.order_timeout', 30),
$db
);
}
}
步骤 4: 在 dependencies.php 中绑定接口到 Factory
// config/autoload/dependencies.php
return [
// 将接口绑定到 Factory,避免循环依赖
App\Service\OrderServiceInterface::class => App\Factory\OrderServiceFactory::class,
];
使用示例:
namespace App\Controller;
use App\Service\OrderServiceInterface;
use Hyperf\HttpServer\Annotation\AutoController;
#[AutoController]
class OrderController
{
public function __construct(
private OrderServiceInterface $orderService
) {}
public function create()
{
$id = $this->orderService->create(['product_id' => 1]);
return ['id' => $id];
}
}
适用场景:
关键注意:
| 方式 | 适用场景 | 示例 |
|---|---|---|
| 构造函数注入 | 大部分场景(推荐) | __construct(private UserService $service) |
| Factory 工厂 | 复杂初始化、动态创建 | 创建 Factory 类并在 dependencies.php 绑定 |
| Listener 注册 | 应用启动时注册服务 | 监听 BootApplication 事件 |
| 方法注入 | 中间件、事件监听器 | public function handle(Context $ctx, Closure $next) |
| 属性注入 | 不推荐,仅用于特殊情况 | 使用 @Inject 注解 |
| 容器获取 | 无法使用注入的场景 | $container->get(Service::class) |
namespace App\Service;
use App\Repository\UserRepository;
class UserService
{
public function __construct(
private UserRepository $userRepository
) {}
public function findById(int $id): ?array
{
return $this->userRepository->find($id);
}
}
namespace App\Service;
use App\Repository\UserRepository;
use App\Repository\OrderRepository;
use Hyperf\DbConnection\Db;
class OrderService
{
public function __construct(
private UserRepository $userRepository,
private OrderRepository $orderRepository,
private Db $db
) {}
}
当 A 依赖 B,B 又依赖 A 时:
// 方案一:使用容器延迟获取
class ServiceA
{
private ?ServiceB $serviceB = null;
public function __construct(
private \Psr\Container\ContainerInterface $container
) {}
private function getServiceB(): ServiceB
{
if (!$this->serviceB) {
$this->serviceB = $this->container->get(ServiceB::class);
}
return $this->serviceB;
}
}
// 方案二:重构代码,提取共同依赖到第三个服务
// 在任意可注入的地方
public function debug(\Psr\Container\ContainerInterface $container)
{
// 检查服务是否注册
var_dump($container->has(UserService::class));
// 获取服务定义(需要安装 hyperf/di 调试工具)
}