Hyperf 默认使用 Swoole 协程 MySQL 客户端(Co\MySQL),不依赖 PDO;PDO_MySQL 因底层同步阻塞,无法真正协程化,易导致调度异常和连接泄漏;正确方案是通过 hyperf/database 组件实现全协程数据库访问。

Hyperf 默认使用的是 Swoole 的协程 MySQL 客户端(Co\MySQL),不依赖 PDO。所以严格来说,PDO_MySQL 本身不支持协程,Hyperf 也不推荐、不提供“开启 PDO_MySQL 协程”的能力。
为什么 PDO_MySQL 无法协程化?
PDO 是 PHP 的同步扩展,底层调用的是 libmysql 或 mysqlnd,所有操作都会阻塞当前协程。即使在 Swoole 协程环境下,PDO 调用仍会退化为同步 IO,失去协程的并发优势,还可能引发协程调度异常或连接泄漏。
Hyperf 正确的 MySQL 协程方案
Hyperf 原生集成的是 Swoole 协程 MySQL 客户端,通过 Hyperf\Database 组件(基于 co-mysql)实现完全协程化的数据库访问:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 配置文件
config/autoload/databases.php中默认使用'driver' => 'mysql',底层自动走协程客户端 - 无需额外安装
pdo_mysql扩展(但需确保已启用swoole及其协程支持) - Eloquent ORM、Query Builder、原生 SQL 查询全部天然协程安全
如果必须用 PDO(比如兼容旧代码)怎么办?
可以将 PDO 操作包裹在 Co\run 或 go + defer 中,但不推荐用于高频数据库操作:
- 使用
Hyperf\Coroutine\Concurrent限制并发数,避免阻塞过多协程 - 每次 PDO 操作都应显式关闭连接(
$pdo = null),防止连接泄漏 - 仅建议用于低频、非核心路径(如初始化脚本、离线任务)
检查与验证是否协程生效
运行以下命令确认环境就绪:
-
php --ri swoole查看是否启用了mysqlnd支持(Hyperf 2.2+ 推荐启用) - 在协程中执行
var_dump(\Swoole\Coroutine::getPcid()),确保不为false - 用
hyperf/database执行查询后,观察strace -p $(pgrep php)不会出现read/write系统调用阻塞










