hostname必须写127.0.0.1而非localhost,因windows下localhost会走命名管道或ipv6导致sqlstatehy000错误;type和database字段必须显式配置且合法,password为空时mysql 8.0需改认证插件为mysql_native_password。

hostname 必须写 127.0.0.1,不能写 localhost
Windows 下 localhost 会优先走命名管道或 IPv6 回环,而 PHP 的 pdo_mysql 扩展在多数环境(尤其 phpEnv、XAMPP)里只认 IPv4 TCP 连接,结果就是报错 SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client 或直接超时。
解决方案很简单:不管 MySQL 装在本机还是远程,只要用 TCP 连接,hostname 就统一填 127.0.0.1。
- 配置路径是
config/database.php,不是.env(TP8.0 默认不读 .env,除非你手动引入 dotenv) - 别信“localhost 和 127.0.0.1 等价”这种笼统说法——MySQL 认证插件、PHP 驱动、操作系统解析行为三者叠加后,它们行为完全不同
- 验证方式:写个裸脚本
test_db.php,用new mysqli('127.0.0.1', ...)直连,输出 OK 才算真正通
type 和 database 必须存在且值合法
type 缺失时框架会 fallback 到默认 mysql,看似能跑,但一旦你后续切到 pgsql 或 sqlsrv,就会因驱动未注册直接报错;database 若指向一个不存在的库名,TP8 启动时不会立即报错,但首次执行查询就会抛 Unknown database 'xxx',且错误堆栈藏得深,容易误判为连接失败。
这两个字段不是“可选”,是初始化连接对象的强制契约。
-
type必须是小写字符串:'mysql'、'sqlite'、'pgsql',大小写敏感 -
database对应的库必须已由CREATE DATABASE创建好,且账号有USAGE和SELECT权限 - 如果用
Db::connect()动态传参,数组里也必须带这两个键,漏掉任何一个都会导致底层PDO::__construct()失败
password 留空 ≠ 不填,MySQL 8.0 认证插件必须改
phpEnv、XAMPP、Docker 官方镜像等常见环境,默认 root 密码为空,但 MySQL 8.0+ 默认用 caching_sha2_password 插件认证,而 PHP 7.4–8.2 自带的 mysqlnd 驱动不支持它——结果就是 Access denied for user 'root'@'localhost',哪怕密码确实为空。
必须进 MySQL 命令行执行显式切换:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '';
然后 FLUSH PRIVILEGES;,再查 SELECT user, host, plugin FROM mysql.user WHERE user = 'root'; 确认 plugin 列是 mysql_native_password。
- 这个操作只影响指定用户(如
'root'@'localhost'),不影响其他 host 的账号 - 如果你用的是 Docker,可在
my.cnf里加default_authentication_plugin=mysql_native_password永久生效 - 别跳过验证步骤:光改配置不等于连接就通,必须用原生
mysqli或pdo脚本实测
连接池不是配了就生效,Swoole 环境下才起作用
TP8.0 的 database.php 里加 pool、max_connections 字段完全无效。连接池能力由 topthink/think-swoole 扩展提供,且仅在 Swoole 协程服务器下激活。
想让连接复用,三件事缺一不可:
- 启动方式必须是
php think swoole,不是php think run - 配置入口是
config/swoole.php中的database节点,且enable => true - 代码里必须显式调用
Db::pool()->table(...),Db::table()默认仍走短连接
最容易被忽略的是协程并发量和池容量的对齐:一个 Worker 开 100 个协程查库,但池子只有 8 个连接,剩下 92 个协程就在等 wait_timeout,压测时照样报 Too many connections。这时候调大池子没用,得先看 swoole.server.worker_num 和 MySQL 的 max_connections 是否撑得住。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











