thinkphp5需在config/database.php数据库配置数组中明确定义'hostport'=>3307(整数),而非'port';.env中设db_port=3307需确保config::loadenv()已执行;动态连接db::connect()必须显式传入hostport;验证须查调试日志dsn或抓包确认实际连接端口。

ThinkPHP5 修改数据库端口,不是改环境变量、不是改驱动源码、也不是靠自动探测——它只认你明确定义的 hostport(配置文件或动态连接时)或 DB_PORT(.env 中),且必须确保该配置被实际加载、未被覆盖。
config/database.php 里怎么加端口?
在对应数据库连接配置数组中,直接添加 'hostport' => 3307(注意是整数,不是字符串)。
-
hostport是 ThinkPHP 的配置键名,不是标准 PDO 的port;它最终会被拼进 DSN:mysql:host=127.0.0.1;port=3307;dbname=test - 别写成
'port' => 3307—— 框架不识别这个键,会静默忽略,回退到默认 3306 - 如果用了多环境配置(如
mysql2分组),确认你改的是当前实际生效的分组,而不是default或其他未被引用的组 - 修改后清空 runtime/cache/ 下的配置缓存,否则可能仍读旧值
用 .env 设置端口要注意什么?
DB_PORT=3307 这行必须存在,且前提是 think\facade\Config::loadEnv() 已执行(通常入口文件已做),否则 .env 根本不加载。
- 检查是否启用了
.env加载:搜索项目中是否有Config::loadEnv()调用,尤其在base.php或start.php -
DB_PORT值会被映射为配置中的hostport,所以无需再在database.php里重复写 - 如果同时在
database.php和.env中定义了hostport,后者优先级更高 —— 但前提是.env加载成功 - 常见错误:写了
DB_PORT=3307,但Config::loadEnv()被注释或漏调,结果连接还是打到 3306
Db::connect() 动态连接时端口为什么总不生效?
因为动态连接绕过了全局配置合并逻辑,所有字段都得手动给全;hostport 缺失就铁定走 3306。
- 必须显式传入
'hostport' => 3307,不能依赖“其他参数和默认一样,端口应该也一样”的假设 - 示例正确写法:
Db::connect([ 'type' => 'mysql', 'hostname' => '127.0.0.1', 'database' => 'test', 'username' => 'root', 'password' => '', 'hostport' => 3307, // 必须有,且是整数 'charset' => 'utf8mb4' ]); - 错误写法:
'port' => 3307、'hostport' => '3307'(字符串)、或直接省略该键 - DSN 字符串方式虽可绕过键名问题(如
mysql://root:@localhost:3307/test),但维护性差,不推荐用于生产配置
怎么验证端口真改成功了?
别只打印配置数组看有没有 hostport,那只是“写进去了”,不代表“用上了”。最可靠的是看实际发起的连接。
- 开启数据库调试:
'debug' => true,然后查日志里生成的完整 DSN 字符串,确认含;port=3307; - 遇到
Connection refused (111)且日志或报错明确指向127.0.0.1:3306,说明端口根本没生效,90% 是配置位置错、加载失败或键名写错 - 终极验证:用
tcpdump或netstat -an | grep :3307抓包,看 PHP 进程是否真连向目标端口 - 注意:PDO DSN 拼接发生在底层,ThinkPHP 不做端口 fallback,写错或缺失就是 3306,不会报“端口配置无效”这类提示
真正容易被忽略的是配置加载顺序和键名一致性:hostport 这个名字必须拼对,且必须出现在最终被 Db::connect() 实际读取的那个配置层级里——它不在驱动类里,也不在 params 数组里,就在连接配置顶层。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











