应根据环境选择:本地linux/macos开发用localhost走unix套接字,windows或docker环境用127.0.0.1走tcp/ip;docker中需改用容器名或宿主机ip,避免localhost解析歧义。

ThinkPHP 数据库配置里的 hostname 填 localhost 还是 127.0.0.1,关键看你的 MySQL 服务怎么监听、是否启用了 Unix 域套接字,以及你是否需要跨平台或容器环境稳定运行。
MySQL 对 localhost 的特殊处理
MySQL 客户端遇到 localhost 时,默认不走 TCP/IP,而是尝试用 Unix 域套接字(socket) 连接。这在 Linux/macOS 本地开发中很常见,速度快、权限控制更细,但前提是:
- MySQL 服务已启用 socket(默认开启,路径如
/var/run/mysqld/mysqld.sock) - PHP 运行用户有读取该 socket 文件的权限
- ThinkPHP 没强制指定端口或协议(如加
:3306会退化为 TCP)
而填 127.0.0.1 会强制走 TCP/IP 协议,绕过 socket,依赖 MySQL 监听 3306 端口且 bind-address 允许该地址。
容器和 Docker 环境建议用 127.0.0.1
在 Docker 容器里,localhost 指的是容器自身,不是宿主机。如果你的 MySQL 在宿主机或另一个容器中:
- 填
localhost→ 尝试连容器内部的 3306 或 socket → 必然失败 - 填
127.0.0.1→ 仍连容器自身(除非网络模式是 host) - 正确做法:填宿主机网关 IP(如
172.17.0.1)或 MySQL 容器名(Docker Compose 场景)
所以“localhost vs 127.0.0.1”在容器里本身不是最优解——真正要改的是目标地址,而非纠结这两个词。
IPv6 和 hosts 解析可能悄悄搞破坏
现代系统常把 localhost 解析成 ::1(IPv6)。如果 MySQL 只监听 IPv4(bind-address = 127.0.0.1),而 PHP 用 localhost 连,就可能因协议不匹配失败,报错类似 Connection refused。
验证方式:
- Linux/macOS:
getent hosts localhost或ping -c1 localhost | head -1 - Windows:
ping localhost看返回的是 127.0.0.1 还是 ::1
若解析为 ::1,又不想改 MySQL 配置,直接把 hostname 改成 127.0.0.1 最省事。
推荐写法与场景总结
不追求绝对统一,按实际环境选:
-
本地开发(Linux/macOS + MySQL 默认安装):用
localhost,享受 socket 连接的简洁和性能 -
Windows 开发 / WAMP/MAMP 环境:倾向用
127.0.0.1,避免 socket 路径不一致或权限问题 -
Docker / 多容器部署:不用这两个,改用服务名(如
mysql)或宿主机特定 IP -
生产环境或需明确协议控制:一律用
127.0.0.1,规避解析不确定性
ThinkPHP 示例配置中写 'hostname' => 'localhost' 没问题,但一旦连不上,先检查是不是解析或 socket 权限导致的——而不是立刻怀疑代码写错了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











