PHP应用远程连接Heroku PostgreSQL数据库的两类问题求助
解决GoDaddy PHP应用连接Heroku PostgreSQL的问题
我之前帮朋友处理过类似的跨主机PostgreSQL连接问题,刚好能给你一些实用的解决方案,一步步来解决你的两个难题:
一、搞定Heroku PostgreSQL的有效连接凭证
Heroku的DATABASE_URL确实会定期自动轮换默认凭证,直接硬编码临时凭证肯定会失效,这里有两个长期可行的方案:
1. 创建带静态凭证的自定义数据库用户
你可以给Heroku数据库添加一个自己控制的用户,这个用户的凭证不会被自动轮换:
- 打开Heroku CLI,登录并选择你的应用:
heroku login heroku apps:select your-app-name - 创建新用户(替换成你要的用户名和强密码):
heroku pg:psql -c "CREATE USER your-static-user WITH PASSWORD 'your-strong-password';" - 给这个用户分配数据库权限(替换成你的数据库名):
heroku pg:psql -c "GRANT ALL PRIVILEGES ON DATABASE your-db-name TO your-static-user;" - 最后获取完整的连接信息:
这个命令会返回类似heroku pg:credentials:url your-static-userpostgres://your-static-user:xxx@ec2-xx-xx-xx-xx.compute-1.amazonaws.com:5432/your-db-name的URL,你可以拆分出主机、端口、用户名等信息直接用。
2. 用Heroku API实时拉取DATABASE_URL
如果不想用静态用户,你可以写个简单的PHP脚本定期从Heroku API获取最新的DATABASE_URL:
- 从Heroku账户设置里拿到你的API密钥
- 用PHP发送GET请求到
https://api.heroku.com/apps/your-app-name/config-vars,请求头要包含Authorization: Bearer YOUR_API_KEY和Accept: application/vnd.heroku+json; version=3 - 解析返回的JSON,提取
DATABASE_URL字段后拆分出连接所需的各个参数。
二、解决硬编码凭证无法连接的问题
硬编码连不上基本是两个核心原因:IP白名单限制和SSL强制要求,一个个来解决:
1. 把GoDaddy主机IP加入Heroku PostgreSQL白名单
Heroku的PostgreSQL默认只允许内部网络访问,你需要把GoDaddy主机的公网IP加进去:
- 先查GoDaddy主机的公网IP:可以在GoDaddy控制面板里找,或者用PHP脚本
echo $_SERVER['SERVER_ADDR'];获取 - 在Heroku后台进入你的PostgreSQL资源页面,找到「Settings」→「IP Whitelist」,添加你的GoDaddy主机IP
- 或者用CLI命令快速添加(替换成你的数据库名和IP):
heroku pg:allow-access your-db-name your-godaddy-ip
2. 确保PHP连接时启用SSL
Heroku PostgreSQL强制要求SSL连接,你的代码必须明确开启这个选项:
用pg_query的示例代码:
$host = 'ec2-xx-xx-xx-xx.compute-1.amazonaws.com'; $port = '5432'; $dbname = 'your-db-name'; $user = 'your-static-user'; $password = 'your-strong-password'; // 强制启用SSL的连接字符串 $conn_string = "host=$host port=$port dbname=$dbname user=$user password=$password sslmode=require"; $conn = pg_connect($conn_string); if (!$conn) { die("连接失败: " . pg_last_error()); } // 测试查询 $query = "SELECT * FROM your-table LIMIT 1"; $result = pg_query($conn, $query); if (!$result) { die("查询失败: " . pg_last_error()); } // 处理结果 while ($row = pg_fetch_assoc($result)) { print_r($row); } pg_close($conn);
用PDO的示例代码:
$dsn = "pgsql:host=ec2-xx-xx-xx-xx.compute-1.amazonaws.com;port=5432;dbname=your-db-name;sslmode=require"; $user = 'your-static-user'; $password = 'your-strong-password'; try { $pdo = new PDO($dsn, $user, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 测试查询 $stmt = $pdo->query("SELECT * FROM your-table LIMIT 1"); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { print_r($row); } } catch(PDOException $e) { die("连接或查询失败: " . $e->getMessage()); }
额外排查点
- 确认GoDaddy的PHP环境安装了PostgreSQL扩展:用
phpinfo()查看是否有pgsql和pdo_pgsql模块,如果没有,去GoDaddy控制面板启用或者联系客服开启。 - 检查GoDaddy主机防火墙:确认允许出站连接到5432端口(PostgreSQL默认端口)。
内容的提问来源于stack exchange,提问作者bluemccarty
相关产品推荐
相关产品推荐

