端口冲突根源在MySQL服务未监听或PHP仍连3306:先查MySQL日志确认启动失败原因,再用netstat验证真实监听端口,ThinkPHP需在config/database.php、.env或Db::connect()中显式设整数port=3307并用127.0.0.1替代localhost。

端口冲突不是 ThinkPHP 的错,而是 MySQL 服务没起来或客户端连错了地方——先确认是服务端没监听新端口,还是 PHP 还在往 3306 发请求。
查日志:MySQL 启动失败时别急着改 port,先看是不是配置写错了
ThinkPHP 报 SQLSTATE[HY000] [2002] 或 Connection refused (111),很多人立刻去改 config/database.php,结果没用。真正该先看的是 MySQL 自身日志:
- 打开 phpEnv / XAMPP / phpStudy 的控制面板,点 MySQL 行右侧的 Logs,翻到末尾找这句:
Can't start server: Bind on TCP/IP port——只有它出现,才说明 3306 真被占了 - 如果看到的是
unknown variable 'innodb_data_file_path'、invalid option或语法错误提示,说明my.ini有硬伤:比如用了中文引号、多了一个空格、port = "3307"写成字符串 - Windows 下保存
my.ini必须选「UTF-8 无 BOM」,否则 MySQL 静默加载失败,日志里可能连错误都不打
改配置:ThinkPHP 中设置 port 的三种方式及优先级
改完 MySQL 服务端口(比如设为 3307),ThinkPHP 客户端必须同步更新,否则它默认仍会连 3306。三种改法不能混用,否则互相覆盖:
-
config/database.php里直接写:'port' => 3307(整数,不是字符串);若同时存在DB_DSN,这个port会被忽略 -
.env文件加:DB_PORT=3307,然后在config/database.php对应位置写:'port' => (int) getenv('DB_PORT') ?: 3306;确保入口文件已执行think\facade\Config::loadEnv() - 运行时用
Db::connect()动态连接,必须传完整数组:['hostname' => '127.0.0.1', 'port' => 3307, 'database' => 'test', ...];漏掉port就回退到 3306
验证监听:别信“重启就成功”,用 netstat 看真实状态
改完配置、重启 MySQL 服务、也更新了 ThinkPHP 配置,还是连不上?跳过猜测,直击系统层:
立即学习“PHP免费学习笔记(深入)”;
- Windows 下立即执行:
netstat -ano | findstr :3307;如果有输出且 PID 对应mysqld.exe,说明服务真在监听 - 如果没输出,但
netstat -ano | findstr :3306仍有结果,说明 MySQL 根本没切到新端口,得回看日志和my.ini路径是否正确 - 确认 phpEnv/XAMPP 是否真读了你改的
my.ini:用控制面板点「配置」按钮打开的才是它实际加载的那个文件,别去改C:\Program Files\MySQL\下的同名文件
连不上时的典型误导点:localhost ≠ 127.0.0.1,命名管道会绕过端口
即使服务监听了 3307,ThinkPHP 或 phpMyAdmin 仍报连 3306 失败,大概率是连接串用了 localhost:
- Windows 下
localhost默认走命名管道(pipe),不走 TCP 端口;必须显式写127.0.0.1:3307才强制走 TCP - phpMyAdmin 要改
config.inc.php里的$cfg['Servers'][$i]['host'] = '127.0.0.1'和$cfg['Servers'][$i]['port'] = '3307',不能只改 host 加冒号 - PDO 连接串里如果用了
mysql:host=localhost;port=3307,Windows 下 port 参数会被忽略;换成mysql:host=127.0.0.1;port=3307才生效
最常被忽略的是:MySQL 服务是否真监听了新端口,以及 ThinkPHP 是否真把 port 值塞进了 PDO DSN。调试时直接打印 Db::getPdo()->getAttribute(PDO::ATTR_CONNECTION_STATUS),比猜日志更可靠。



















