php 8.5.5 连接容器化 mysql 的关键是网络可达性与权限适配:容器间须用服务名(如 mysql)而非 localhost,mysql 用户需授权 'user'@'%' 或具体容器网段 ip,并启用 pdo_mysql/mysqli 扩展;dsn 中 host 必须匹配 docker 网络配置。

PHP 8.5.5 连接容器化 MySQL,关键不是版本兼容性(它完全支持),而是网络可达性、凭据正确性和连接参数适配。本地 localhost 在容器里根本连不到宿主机或另一容器的 MySQL,这是最常卡住的地方。
确认 MySQL 容器暴露端口且可被 PHP 容器访问
容器间不能用 localhost 或 127.0.0.1 互相访问——它们各自有独立的网络栈。必须用 Docker 网络内的服务名或 IP:
- 若两个容器在同一个自定义 bridge 网络(推荐),PHP 应连接
mysql(即 MySQL 容器的service name),而不是localhost - 若 MySQL 运行在宿主机,且 PHP 在容器中,需用宿主机网关 IP(如 Docker Desktop 的
host.docker.internal,Linux 上可能需172.17.0.1) - 检查 MySQL 容器是否真正监听外部连接:
docker exec -it mysql-container mysql -h127.0.0.1 -uroot -p -e "SELECT USER();"成功 ≠ 外部可连;要确认bind-address是0.0.0.0或对应网卡,且skip-networking未启用 - 端口映射必须明确:例如
-p 3306:3306仅对宿主机开放;容器间通信走内部端口(默认 3306),不依赖-p
PDO 连接字符串必须匹配容器网络配置
DSN 中的 host 值决定连接路径,写错就直接超时或拒绝连接:
- PHP 和 MySQL 同属一个 Docker Compose 网络(如
backend):$dsn = "mysql:host=mysql;dbname=testdb;charset=utf8mb4";—— 这里的mysql是docker-compose.yml中 service 的名字 - MySQL 在宿主机,PHP 在容器(Docker Desktop):
$dsn = "mysql:host=host.docker.internal;dbname=testdb;charset=utf8mb4"; - MySQL 在宿主机,PHP 在容器(Linux):
$dsn = "mysql:host=172.17.0.1;dbname=testdb;charset=utf8mb4";(需确认 bridge 网关 IP) - 不要硬编码端口除非必要;默认 3306 可省略;若改了端口(如
3307),DSN 必须显式写:mysql:host=mysql;port=3307;dbname=...
验证 MySQL 用户权限是否允许容器 IP 段登录
MySQL 默认只允许 localhost 或 127.0.0.1 用户登录,而容器 IP 是动态分配的(如 172.20.0.3),必须显式授权:
- 进入 MySQL 容器执行:
CREATE USER 'app'@'%' IDENTIFIED BY 'strongpass';GRANT ALL ON testdb.* TO 'app'@'%';FLUSH PRIVILEGES; - 避免用
root+%,生产环境应限制 IP 段(如'app'@'172.20.0.%') - 检查
user表:SELECT host, user FROM mysql.user;,确认目标用户 host 不是localhost(那只能本机 socket 连) - 如果仍报
Access denied,用mysql -h mysql -u app -p在 PHP 容器里手动测试,排除代码外因素
PHP 8.5.5 需启用扩展且注意 Unix Socket 不适用容器场景
容器内 PHP 默认不使用 Unix Socket(/var/run/mysqld/mysqld.sock),因为 MySQL 容器通常不挂载该路径,强行指定会报 Can't connect to local MySQL server:
- 确保
php.ini启用了extension=pdo_mysql和/或extension=mysqli(PHP 8.5.5 自带,但 Docker 镜像可能未启用) - Dockerfile 中加一句:
RUN docker-php-ext-enable pdo_mysql mysqli - 不要在 DSN 中写
unix_socket=/path/to/socket,除非你明确挂载并配置了 socket 文件路径(极少见且易出错) - 用
php -m | grep -E "(pdo|mysqli)"在 PHP 容器里验证扩展已加载
最容易被忽略的是:Docker Compose 服务名大小写敏感、网络未共享、MySQL 用户 host 写死为 localhost,以及 PHP 容器 DNS 解析失败(可临时用 ping mysql 测试)。连通性问题几乎全出在网络层和权限层,而非 PHP 代码本身。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











