根源是phpMyAdmin 4.9+默认启用servers.php自动发现和blowfish_secret自动生成,导致config.inc.php中手动配置的$cfg'Servers'等被后续加载的servers.php或环境变量逻辑覆盖,表现为登录后连接地址与配置不符或auth_type失效。
phpMyAdmin 4.9+ 的 $cfg['Servers'] 被覆盖的根源是配置加载顺序
新版 phpmyadmin(4.9 及以后)默认启用 blowfish_secret 自动生成和 servers.php 自动发现机制,导致你手动在 config.inc.php 中写的 $cfg['servers'][1] 等配置,可能被后续加载的 servers.php 或环境变量注入逻辑覆盖。
常见现象:你在 config.inc.php 里明确写了 $cfg['Servers'][1]['host'] = '10.0.2.10';,但登录后看到连接的是 localhost;或者修改了 auth_type 却没生效——大概率是配置被重写了。
-
servers.php若存在(尤其在./config/下),会被自动include,且执行时机晚于config.inc.php - Docker 镜像(如
phpmyadmin/phpmyadmin)会通过环境变量生成servers.php,强制覆盖你的$cfg['Servers'] - PHP 的
include是顺序执行,后 include 的文件中对$cfg['Servers']的赋值会直接替换前一个
如何确认是否被 servers.php 覆盖
最直接的办法是查加载链。打开 phpMyAdmin 根目录下的 libraries/vendor_config.php(或 vendor_config.php),搜索 include 和 servers.php;再检查 config/ 目录是否存在 servers.php。
- 运行
grep -r "servers\.php" . --include="*.php"查看哪些文件include它 - 在
config.inc.php结尾加一行:error_log('Servers count: ' . count($cfg['Servers']));,然后看 PHP 错误日志输出几次 - 如果日志里显示
Servers count: 0→ 后续被清空重置;显示1但内容不对 → 被后续赋值覆盖
$cfg['Servers'] 初始化必须用 array_merge_recursive 吗
不是必须,但「直接赋值」$cfg['Servers'][1] = [...] 在多服务器场景下极脆弱。phpMyAdmin 内部逻辑依赖 $cfg['Servers'] 是一个以数字为键的连续数组,且索引从 1 开始;若你只设 [1],而 servers.php 又写入了 [1] 和 [2],就会发生覆盖而非合并。
更稳妥的做法是:先保留原始结构,再按需修改字段:
立即学习“PHP免费学习笔记(深入)”;
$cfg['Servers'][1]['host'] = '10.0.2.10'; $cfg['Servers'][1]['port'] = '3307'; $cfg['Servers'][1]['auth_type'] = 'cookie'; // 不要 unset($cfg['Servers']); 不要 $cfg['Servers'] = [];
- 避免使用
$cfg['Servers'] = []或unset($cfg['Servers'])—— 这会清掉所有已有定义,包括系统预设的默认值 - 不要用
array_merge($cfg['Servers'], [...]):它会重索引,把[1]变成[0],导致 phpMyAdmin 找不到服务器 - 若需动态合并多个配置源,用
array_replace_recursive(),但仅限你完全控制整个加载流程时
Docker 环境下绕过 servers.php 覆盖的实操方式
官方 Docker 镜像默认挂载 /etc/phpmyadmin/servers.php,且该文件由 entrypoint 脚本根据环境变量(如 PMA_HOST)生成。想保留手写配置,必须切断这个流程。
- 启动容器时加
-v /dev/null:/etc/phpmyadmin/servers.php,让脚本写入失败,从而 fallback 到config.inc.php - 或改用
phpmyadmin/phpmyadmin:5.2-apache镜像后,自定义entrypoint.sh,跳过generate-servers-php步骤 - 最简单有效:把完整服务器配置写进
config.inc.php,然后在容器启动命令里加-e PMA_ARBITRARY=1并禁用自动发现(-e PMA_CONFIG_BASE64=...编码你的 config)
复杂点在于:一旦用了 PMA_ARBITRARY=1,用户界面上会出现“任意服务器”输入框,但如果你已固定只连一台,这个入口反而成了干扰项——得靠 CSS 或 Nginx 重写隐藏,这点容易被忽略。



















