hy000是mysql通用错误标识,非具体错误码,本质是客户端未透传真实错误码(如2002、1045、1366等),需结合错误消息中紧随其后的数字错误码及日志定位根本原因。

CodeIgniter4 报 SQLSTATE[HY000],本质是 PDO 或 MySQL 客户端未透传真实错误码,只返回了通用兜底标识。你必须结合紧随其后的数字错误码(如 [2002]、[1045]、[1366] 等)或完整错误消息来定位,不能只盯着 HY000。
查清真实错误码和上下文
HY000 本身不说明问题,它只是“不知道该报啥,先报个通用的”。关键动作是:
- 看完整错误字符串——比如
SQLSTATE[HY000] [2002] Connection refused,重点就是 [2002],代表连接失败;SQLSTATE[HY000] [1366] Incorrect string value,重点就是 [1366],代表字符集插入失败 - 打开 CI4 的调试模式:在
.env中设CI_ENVIRONMENT = development,确保错误详情可见 - 查 MySQL 错误日志:
tail -f /var/log/mysql/error.log(Linux)或查看 Windows 事件查看器中的 MySQL 日志,服务端实际报错往往更明确 - 用命令行直连验证:
mysql -h 127.0.0.1 -P 3306 -u your_user -p -e "SELECT 1;",绕过框架看是否同样失败
常见真实错误及对应处理
根据高频场景,快速匹配并处理:
-
[2002] Connection refused:MySQL 服务没运行、端口未监听、防火墙拦截、或 CI4 配置里用了
localhost却被系统解析为 socket 连接(而 MySQL 没配 socket)。解决:确认systemctl status mysql正常;改配置中hostname为127.0.0.1强制走 TCP;检查netstat -tulnp | grep :3306 -
[1045] Access denied:用户名密码错、用户无从该 host 连接权限、或 MySQL 8.0+ 的
caching_sha2_password认证插件不兼容旧驱动。解决:进 MySQL 执行SELECT user, host FROM mysql.user;确认用户存在且 host 匹配;必要时执行ALTER USER 'user'@'host' IDENTIFIED WITH mysql_native_password BY 'pass'; -
[1366] Incorrect string value:插入四字节字符(如 emoji)但表/字段不是 utf8mb4。CI4 的数据库配置中仅设
'charset' => 'utf8mb4'不够,必须在 DSN 里写死:'DSN' => 'mysql:host=127.0.0.1;dbname=test;charset=utf8mb4';同时 MySQL 服务端要配置character-set-server = utf8mb4并重启,已有表需执行ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -
[1267] Illegal mix of collations:JOIN 或 WHERE 中字段排序规则不一致(如一个字段是
utf8mb4_0900_ai_ci,另一个是utf8mb4_unicode_ci)。解决:统一数据库、表、字段三级 collation;或在 SQL 中显式加COLLATE utf8mb4_unicode_ci
CI4 特定配置要点
CodeIgniter4 的数据库层有几处容易踩坑的细节:
-
app/Config/Database.php中的'charset'和'DBCollat'只影响连接初始化时的会话变量,不会改变已建表结构。若表本身是 latin1 或 utf8,光改配置无效 - 务必禁用
PDO::ATTR_EMULATE_PREPARES(CI4 默认关闭),否则某些字符集行为异常;如需开启缓冲查询防 2014 错误,加'DBDebug' => true并在'DSN'后补充;PDO::MYSQL_ATTR_USE_BUFFERED_QUERY=true - Docker 环境下,CI4 容器连接 MySQL 容器时,
hostname必须填 docker-compose 中定义的服务名(如db),不能填localhost或127.0.0.1











