Hyperf 中不能直接用 @Inject 注入 PoolFactory,因其未注册到 DI 容器,而是由 Database 组件按配置动态创建并缓存在 DatabaseManager 中;应通过注入 DatabaseManager 并调用 getFactory('default') 获取,或更推荐使用 Db 门面或 Database 实例自动管理连接池。

Hyperf 中不能直接用 @Inject 注入 PoolFactory 实例来获取数据库连接池 —— 它不是容器中注册的可注入服务,而是由 Database 组件内部按配置动态构建的工厂集合。
为什么 @Inject 无法注入 PoolFactory
PoolFactory 类本身不被绑定到 DI 容器,Hyperf 的 Database 组件在启动时根据 database.php 配置,为每个数据库配置(如 default、redis)创建独立的 PoolFactory 实例,并缓存在 DatabaseManager 内部。你无法通过 @Inject 声明式获取它。
- 尝试
@Inject PoolFactory $factory会报错:Entry "PoolFactory" cannot be resolved -
PoolFactory是具体实现类,不是接口,且未加@Injectable或手动$container->set() - 即使手动 bind,也无法匹配多库场景下的“哪个 pool”
正确方式:通过 DatabaseManager 获取指定名称的 PoolFactory
你需要先注入 DatabaseManager,再调用其 getFactory(string $name) 方法拿到对应数据库配置的 PoolFactory 实例。这个 $name 就是 config/database.php 里定义的键名(如 default)。
-
DatabaseManager是容器中注册的服务,支持@Inject -
getFactory('default')返回的是PoolFactory,可用于手动acquire()/release() - 注意:该 factory 返回的是
ConnectionInterface,不是 PDO 原生对象
use Hyperf\Database\ConnectionInterface;
use Hyperf\Database\Pool\PoolFactory;
use Hyperf\Database\Manager as DatabaseManager;
<p>class UserService
{
public function __construct(
private DatabaseManager $dbManager
) {}</p><pre class="brush:php;toolbar:false;">public function getUserById(int $id): array
{
// 获取 default 数据库对应的 PoolFactory
$factory = $this->dbManager->getFactory('default');
// 手动从连接池取一个连接
$conn = $factory->acquire();
try {
return $conn->selectOne('SELECT * FROM users WHERE id = ?', [$id]);
} finally {
// 必须归还,否则连接泄漏
$factory->release($conn);
}
}}
更推荐的做法:直接使用 Db 或 Database 门面
99% 的业务场景不需要接触 PoolFactory。Hyperf 已封装好自动连接获取/释放逻辑,用 Db 或注入 Database 即可安全复用连接池。
-
Db::select(...)底层自动调用getFactory()->acquire()并保证release() - 注入
Database后调用$this->database->connection('default')同样走池管理 - 避免手动 acquire/release —— 忘记 release 会导致连接耗尽,这是最常踩的坑
如果真要自定义连接池行为(比如监控或超时拦截)
需要改写 PoolFactory 的构造逻辑,而不是注入它。做法是在 dependencies.php 中替换 DatabaseManager 的构造依赖,或监听 Hyperf\Database\Event\ConnectionCreated 事件做包装。
- 不要试图 patch
PoolFactory类本身,它没有生命周期钩子 - 真正需要控制连接生命周期时,应扩展
ConnectionInterface实现,而非操作 factory - Hyperf v3.1+ 开始,
PoolFactory构造参数已改为私有属性,反射修改风险极高
连接池的“属性注入”本质是误解 —— 它不是靠 DI 注入的组件,而是配置驱动的运行时产物。想用好池,重点在配对 max_connections 和业务并发量,而不是绕过框架封装去碰 PoolFactory。


















