pg_hba.conf中host规则需覆盖php实际连接路径,因host=localhost默认解析为127.0.0.1(ipv4),若仅配置local规则而遗漏对应host行,将导致认证失败;应添加host all all 127.0.0.1/32 md5并重载配置。

pg_hba.conf 里 host 规则没覆盖 PHP 的实际连接路径
PHP 调用 pg_connect() 时,哪怕写的是 host=localhost,默认也会被解析成 IPv4 的 127.0.0.1(除非系统强制优先走 IPv6),而 PostgreSQL 查匹配规则时,只看 pg_hba.conf 中 host 行是否满足「连接方式 + 客户端地址 + 数据库 + 用户」四要素。很多人只改了 local 行(Unix socket),却漏掉 host 行,导致认证直接 fallback 到下一条甚至 reject。
验证方法:用命令行模拟 PHP 的连接行为:psql -h 127.0.0.1 -U your_user -d your_db。如果这条失败,pg_connect() 必然失败。
- 在
pg_hba.conf末尾加一行明确规则(开发环境):host all all 127.0.0.1/32 md5 - 若 PHP 和 PostgreSQL 不在同一机器,把
127.0.0.1/32换成真实来源 IP 或网段,如192.168.1.0/24 - 修改后必须重载配置:
sudo systemctl reload postgresql或SELECT pg_reload_conf();(需有权限) - 检查当前生效规则:
sudo -u postgres psql -c "SELECT * FROM pg_hba_file_rules();"
PHP 连接串写成 host=localhost 却触发了 peer 认证
host=localhost 在 PostgreSQL 看来是模糊的:它可能走 Unix socket(触发 local 行的 peer 认证),也可能走 TCP(触发 host 行)。而 peer 要求系统用户名和数据库用户名完全一致,PHP 进程通常以 www-data 或 apache 身份运行,根本不可能匹配 postgres 用户 —— 这就是为什么连对密码也报错。
解决办法是绕过歧义,强制走 TCP 并指定认证方式:
- 连接串里显式写
host=127.0.0.1 port=5432,不要用localhost - 确保对应
pg_hba.conf行是md5或password,不是peer、ident或trust - PDO 连接示例:
"pgsql:host=127.0.0.1;port=5432;dbname=your_db;user=your_user;password=your_pass"
PostgreSQL 用 scram-sha-256 加密密码,但 PHP 扩展不支持
PostgreSQL 10+ 默认启用 scram-sha-256 密码加密,而 PHP 7.4 及更早版本的 pgsql 扩展(含 pdo_pgsql)底层依赖的 libpq 版本太低,无法完成 SCRAM 握手 —— 此时不会报“不支持”,而是静默认证失败,日志里只显示 password authentication failed。
临时解法是降级服务端密码加密方式:
- 编辑
postgresql.conf,设password_encryption = md5 - 重启或重载 PostgreSQL:
sudo systemctl reload postgresql - 重设用户密码:
ALTER USER your_user WITH PASSWORD 'your_pass'; - 确认生效:
\du your_user应显示密码以md5开头
注意:这不是长期方案,生产环境应升级 PHP(≥8.1)及对应 libpq,并确保编译时链接的是 PostgreSQL ≥10 的客户端库。
PHP 扩展未启用或版本不匹配
即使 pg_hba.conf 和连接串都对,pg_connect() 仍可能报错“无法连接到服务器”,本质是扩展没加载或与 PostgreSQL 服务端协议不兼容。
检查步骤:
- 运行
php -m | grep pgsql,确认pgsql和pdo_pgsql都在列表中 - 创建
info.php调用phpinfo(),搜索pgsql,核对PostgreSQL (libpq) Version是否 ≥ 服务端版本 - MAMP/XAMPP 用户:进偏好设置 → PHP → 勾选
pgsql和pdo_pgsql,然后**彻底重启整个 MAMP 服务**(不是刷新页面) - Linux 下若用源码编译 PHP,需确认 configure 时加了
--with-pgsql和--with-pdo-pgsql
最容易被忽略的是:改完 php.ini 后没重启 Web 服务,或者 CLI 和 Web 使用的不是同一份配置 —— php --ini 和 phpinfo() 显示的路径必须一致。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











