You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP通过Web API连接PostgreSQL失败问题求助

问题描述

我有一套POS系统的Web API脚本,可通过表单提交执行查询语句(如select sum(antal*pris) from batch_salg where fakturadate = '2023-08-25')并成功获取数据,调用方式为fetch_from_table($serverurl,$db,$saldiuser,$api_key,$select,$from,$where,$order_by,$limit);,相关参数如下:

$serverurl="https://somedomain/pos/api";
$saldiuser = 'apiuser';
$db='posdb_9945864';
$api_key='dsdkfswaewmfmkev4546';

我仅熟悉MySQL,尝试使用pg_connect直接连接PostgreSQL,代码如下:

pg_connect(DB_HOST, DB_USER, DB_PASSWORD) or die(pg_error()); 
pg_select_db(DB_DATABASE) or die(pg_error()); 

$sho1_pg = pg_query("SELECT sum (antal*pris)  FROM batch_salg WHERE fakturadate ='$date_today'")
or die(pg_error());  
$shop1_row = pg_fetch_array($sho1_pg);
$shop1_today = $shop1_row['sum'];

但该连接方式失败,报错信息如下:

Warning: pg_connect() [function.pg-connect]: Unable to connect to PostgreSQL server: invalid port number: "pos_99" in /var/www/genogbrug.dk/stuff/jk1.php on line 24
Connection attempt failed.

补充说明:之前可用的Web API代码未定义端口号,我尝试用已有参数结合原MySQL习惯的方式连接却失败,寻求解决方法。以下是可用的Web API完整代码:

<html>
 <body>

<?php

  
   
(isset($_GET['action']))?$action=$_GET['action']:$action=NULL;

(isset($_POST['select']))?$select=$_POST['select']:$select=NULL;
(isset($_POST['from']))?$from=$_POST['from']:$from=NULL;
(isset($_POST['where']))?$where=$_POST['where']:$where=NULL;
(isset($_POST['order_by']))?$order_by=$_POST['order_by']:$order_by=NULL;
(isset($_POST['limit']))?$limit=$_POST['limit']:$limit=NULL;
(isset($_POST['update']))?$update=$_POST['update']:$update=NULL;
(isset($_POST['set']))?$set=$_POST['set']:$set=NULL;
(isset($_POST['insert']))?$insert=$_POST['insert']:$insert=NULL;
(isset($_POST['fields']))?$fields=$_POST['fields']:$fields=NULL;
(isset($_POST['values']))?$values=$_POST['values']:$values=NULL;

if (isset($_GET['select'])) $select=$_GET['select'];
if (isset($_GET['from'])) $from=$_GET['from'];
if (isset($_GET['where'])) $where=$_GET['where'];
if (isset($_GET['order_by'])) $order_by=$_GET['order_by'];
if (isset($_GET['update'])) $update=$_GET['update'];
if (isset($_GET['set'])) $set=$_GET['set'];
if (isset($_GET['insert'])) $insert=$_GET['insert'];
if (isset($_GET['fields'])) $fields=$_GET['fields'];
if (isset($_GET['values'])) $values=$_GET['values'];

$serverurl="https://somedomain.com/pos/api";
$saldiuser = 'apiuser';
$db='DBname';
$api_key='125155dfgtr5trg5t1tr5t';

if ($action) {
    if ($action == 'fetch_from_table') fetch_from_table($serverurl,$db,$saldiuser,$api_key,$select,$from,$where,$order_by,$limit);
    elseif ($action == 'update_table') update_table($serverurl,$db,$saldiuser,$api_key,$update,$set,$where);
    elseif ($action == 'insert_into_table') insert_into_table($serverurl,$saldiuser,$db,$api_key,$insert,$fields,$values);
} else {
  print "<form name=\"rest_api_client\" action=\"rest_api_client.php?action=fetch_from_table\" method='post'>\n";
    print "<table><tbody>";
  print "<tr><td>Select</td><td><input style=\"width:1000px;\" type='text' name='select' value=\"$select\"></td></tr>\n";
    print "<tr><td>From</td><td><input style=\"width:1000px;\" type='text' name='from' value=\"$from\"></td></tr>";
    print "<tr><td>Where</td><td><input style=\"width:1000px;\" type='text' name='where' value=\"$where\"></td></tr>";
    print "<tr><td>Order by</td><td><input style=\"width:1000px;\" type='text' name='order_by' value=\"$order_by\"></td></tr>";
    print "<tr><td>Limit</td><td><input style=\"width:1000px;\" type='text' name='limit' value=\"$limit\"></td></tr>";
    print "<tr><td colspan='2' align='center'><input type='submit' name='go' value='Go'></td></tr>\n";
    print "</tbody></table>";
    print "</form>";
  print "<form name=\"rest_api_client\" action=\"rest_api_client.php?action=update_table\" method='post'>\n";
    print "<table><tbody>";
  print "<tr><td>Update</td><td><input style=\"width:1000px;\" type='text' name='update' value=\"$update\"></td></tr>\n";
    print "<tr><td>Set</td><td><input style=\"width:1000px;\" type='text' name='set' value=\"$set\"></td></tr>";
    print "<tr><td>Where</td><td><input style=\"width:1000px;\" type='text' name='where' value=\"$where\"></td></tr>";
    print "<tr><td colspan='2' align='center'><input type='submit' name='go' value='Go'></td></tr>\n";
    print "</tbody></table>";
    print "</form>";
    print "<form name=\"rest_api_client\" action=\"rest_api_client.php?action=insert_into_table\" method='post'>\n";
    print "<table><tbody>";
  print "<tr><td>Insert into</td><td><input style=\"width:1000px;\" type='text' name='insert' value=\"$insert\"></td></tr>\n";
    print "<tr><td>Fields</td><td><input style=\"width:1000px;\" type='text' name='fields' value=\"$fields\"></td></tr>";
    print "<tr><td>Values</td><td><input style=\"width:1000px;\" type='text' name='values' value=\"$values\"></td></tr>";
    print "<tr><td colspan='2' align='center'><input type='submit' name='go' value='Go'></td></tr>\n";
    print "</tbody></table>";
    print "</form>";

}
function fetch_from_table($serverurl,$db,$saldiuser,$api_key,$select,$from,$where,$order_by,$limit) {
  $result = file_get_contents($serverurl."/rest_api.php?action=fetch_from_table&saldiuser=$saldiuser&db=$db&key=$api_key&select=".urlencode($select)."&from=".urlencode($from)."&where=".urlencode($where)."&order_by=".urlencode($order_by)."&limit=".urlencode($limit));
  $result = json_decode($result, true);
    if (!is_array($result)) {
        print "error: ".$result;
    } else {
        print "<table border='1'><tbody>";
        $rows=count($result);
        $cols=count($result[0]);
        for ($x=0;$x<$rows;$x++){
            print  "<tr>";
            for ($y=0;$y<$cols;$y++) {
                print "<td>".$result[$x][$y]."</td>";
            }
            print  "</tr>";
        }
        print "</tbody></table>";
    }
    print "<a href=\"rest_api_client.php?select=$select&from=$from&where=$where&order_by=$order_by&limit=$limit\">Return to query page</a>";
}
function update_table($serverurl,$db,$saldiuser,$api_key,$update,$set,$where) {
  $result = file_get_contents($serverurl."/rest_api.php?action=update_table&db=$db&saldiuser=$saldiuser&key=$api_key&update=".urlencode($update)."&set=".urlencode($set)."&where=".urlencode($where));
  $result = json_decode($result, true);
    if (!is_numeric($result)) {
        print "error: ".$result;
    } else {
        print "<table border='1'><tbody>";
        print "<td>".$result."</td>";
        print  "</tr>";
        print "</tbody></table>";
    }
    print "<br><a href=\"rest_api_client.php?update=$update&set=$set&where=$where\">Return to query page</a>";
}
function insert_into_table($serverurl,$db,$saldiuser,$api_key,$insert,$fields,$values) {
  $result = file_get_contents($serverurl."/rest_api.php?action=insert_into_table&saldiuser=$saldiuser&db=$db&key=$api_key&insert=".urlencode($insert)."&fields=".urlencode($fields)."&values=".urlencode($values));
  $result = json_decode($result, true);
    if (!is_numeric($result)) {
        print "error: ".$result;
    } else {
        print "<table border='1'><tbody>";
        print "<td>".$result."</td>";
        print  "</tr>";
        print "</tbody></table>";
    }
    print "<br><a href=\"rest_api_client.php?insert=$insert&fields=$fields&values=$values\">Return to query page</a>";
}

?>
 </body>
</html>
解决方案

1. 错误原因

pg_connect的参数逻辑和MySQL的连接函数完全不同:

  • MySQL允许分开传入主机、用户、密码等参数,但PostgreSQL的pg_connect要求传入完整的连接字符串,或使用命名参数格式。
  • 你当前的调用方式会让PostgreSQL错误解析DB_HOST的内容,把其中非数字的部分当成端口号,导致"invalid port number"报错。
  • 另外,POS系统提供了专用Web API,大概率数据库没有开放直接的外部连接权限,这也是直接连接失败的核心原因之一。

2. 可行方案

方案一:正确使用pg_connect连接格式(仅当数据库允许直接连接时)

如果确认数据库开放了外部连接权限,按照PostgreSQL要求的格式构造连接字符串:

// 替换为实际的主机地址、端口(默认5432)等参数
$conn_str = "host=真实主机地址 port=5432 dbname=".DB_DATABASE." user=".DB_USER." password=".DB_PASSWORD;
$conn = pg_connect($conn_str) or die(pg_last_error());

// 执行查询(给sum结果起别名,方便后续取值)
$query = "SELECT sum(antal*pris) AS total_sum FROM batch_salg WHERE fakturadate = '$date_today'";
$sho1_pg = pg_query($conn, $query) or die(pg_last_error($conn));
$shop1_row = pg_fetch_assoc($sho1_pg);
$shop1_today = $shop1_row['total_sum'];

// 关闭连接
pg_close($conn);

注意:

  • 必须确保你的服务器IP在数据库的白名单/安全组内
  • 避免SQL注入,推荐使用参数化查询:
$query = "SELECT sum(antal*pris) AS total_sum FROM batch_salg WHERE fakturadate = $1";
$params = array($date_today);
$sho1_pg = pg_query_params($conn, $query, $params) or die(pg_last_error($conn));

方案二:复用现有Web API(推荐)

既然已有API能正常工作,直接调用即可,无需折腾数据库连接:

$serverurl="https://somedomain/pos/api";
$saldiuser = 'apiuser';
$db='posdb_9945864';
$api_key='dsdkfswaewmfmkev4546';
$select = "sum(antal*pris)";
$from = "batch_salg";
$where = "fakturadate = '$date_today'";

// 调用API自带的函数
fetch_from_table($serverurl, $db, $saldiuser, $api_key, $select, $from, $where, null, null);

// 或者自定义处理返回结果
$result = file_get_contents($serverurl."/rest_api.php?action=fetch_from_table&saldiuser=$saldiuser&db=$db&key=$api_key&select=".urlencode($select)."&from=".urlencode($from)."&where=".urlencode($where));
$result = json_decode($result, true);
if(is_array($result) && !empty($result)){
    $shop1_today = $result[0][0]; // API返回二维数组,第一行第一列即为sum结果
}

这个方案无需处理数据库权限、端口等问题,直接利用现有接口,稳定性更高。

内容的提问来源于stack exchange,提问作者Krohn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 15:49:50