hostport是ThinkPHP8中唯一有效的数据库端口配置项,必须在connections具体连接数组内以整数形式配置,如'hostport'=>3307;env中的DB_PORT需主动调用env()才生效;动态连接须显式传入hostport;验证需查DSN日志、netstat及防火墙。

hostport 是 ThinkPHP8 中控制数据库端口的唯一有效配置项,不是 port,也不是环境变量里的 DB_PORT 自动映射到 PDO 的 port 参数——它最终会被拼进 DSN:mysql:host=127.0.0.1;port=3307;dbname=test。配错位置、类型或加载顺序,端口就无效。
database.php 里怎么写 hostport 才生效
必须写在具体连接配置数组内部,且值为整数(不是字符串):
'connections' => ['mysql' => [..., 'hostport' => 3307, ...]]- 不能写在顶层、
default键下,也不能写成'port' => '3307'(字符串会触发 PDO 连接失败) - 若用多组连接(如
mysql2),要确认当前Db::connect('mysql2')调用的正是你改了hostport的那个分组 - 常见踩坑:复制了默认配置但忘了改分组名,结果连的是未修改的
mysql组,端口仍是 3306
.env 文件中 DB_PORT=3307 为什么没用
因为 DB_PORT 只在 database.php 中被 env('DB_PORT', '3306') 主动读取时才起作用。如果配置里写的是 'hostport' => env('DB_PORT', 3306),那它才生效;如果直接硬编码 'hostport' => 3306,.env 就完全被忽略。
- 检查
config/database.php中对应连接的hostport行,是否真的调用了env() - 确认
think\facade\Config::loadEnv()已执行(通常在base.php或入口文件里,但自定义启动流程可能跳过) - 运行
php think optimize:config后,.env变更不会自动重载,需清缓存或重启 Swoole worker
Db::connect() 动态连接时端口总走默认 3306
动态连接不合并全局配置,所有键都得手动给全。漏掉 hostport,PDO DSN 就不会带 port=xxx,必然 fallback 到 MySQL 默认端口。
- 必须显式传
'hostport' => 3307,不是'port',也不是'port_number' - 示例正确写法:
Db::connect(['type'=>'mysql', 'hostname'=>'127.0.0.1', 'hostport'=>3307, ...]) - 注意:SQL Server 场景下也用
hostport,不是port;即使驱动是sqlsrv,ThinkPHP 统一抽象为hostport - 验证方式:开启
'debug'=>true,查日志里打印出的 DSN 字符串,看是否有port=3307
端口配置生效但连不上?重点查这三处
配置对了 ≠ 连得通。最常被忽略的是底层网络和权限层限制:
立即学习“PHP免费学习笔记(深入)”;
- MySQL 服务本身是否监听该端口?运行
netstat -an | findstr :3307(Windows)或ss -tuln | grep :3307(Linux)确认 - 防火墙是否放行?尤其是 Windows Server 默认阻止非 3306 端口,需手动添加入站规则
- MySQL 用户权限是否绑定 IP+端口?
CREATE USER 'root'@'127.0.0.1' IDENTIFIED BY 'xxx';和'127.0.0.1:3307'不等价,MySQL 不识别带端口的 host - 错误提示
Connection refused (111)指向127.0.0.1:3306?说明配置根本没生效,回退查前三个副标题



















