pg_fetch_assoc

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

pg_fetch_assoc将一行作为关联数组获取

说明

pg_fetch_assoc(PgSql\Result $result, ?int $row = null): array|false

pg_fetch_assoc() 返回与所获取行(记录)对应的关联数组。

pg_fetch_assoc() 等同于调用 pg_fetch_array(),并将 PGSQL_ASSOC 作为可选的第三个参数。它只返回一个关联数组。如果您需要数字索引,请使用 pg_fetch_row()

注意: 此函数将 NULL 字段设置为 PHP null 值。

pg_fetch_assoc() 的速度与使用 pg_fetch_row() 相比并没有显著下降,而且使用起来更加容易。

参数

result

pg_query()pg_query_params()pg_execute()(以及其他)返回的 PgSql\Result 实例。

row

要获取的结果集中行的编号。行从 0 开始编号。如果省略或为 null,则获取下一行。

返回值

一个按关联方式(按字段名)索引的 arrayarray 中的每个值都表示为一个 string。数据库 NULL 值将返回为 null

如果 row 超出集合中的行数,没有更多行,或者发生任何其他错误,则返回 false

变更日志

版本 说明
8.1.0 result 参数现在期望一个 PgSql\Result 实例;以前,期望的是一个 resource

范例

示例 #1 pg_fetch_assoc() 示例

<?php
$conn
= pg_connect("dbname=publisher");
if (!
$conn) {
echo
"发生错误。\n";
exit;
}

$result = pg_query($conn, "SELECT id, author, email FROM authors");
if (!
$result) {
echo
"发生错误。\n";
exit;
}

while (
$row = pg_fetch_assoc($result)) {
echo
$row['id'];
echo
$row['author'];
echo
$row['email'];
}
?>

参见

添加备注

用户贡献的备注 17 个备注

13
slurppp at hotmail dot fr
12 年前
请注意,所有 pg_fetch_* 函数都忽略了数据的原始类型,并且始终返回字符串。(对于数字也是如此)
3
匿名
15 年前
当心!如果您的查询返回多个名称相同的列,则结果数组中只会包含最右边的列。如果您使用的是联接组合,这可能会导致问题。

例如
<?php
// 假设 'pkey' 是表 a 和 b 的主键列(主键从不为空)
$res = pg_query("Select a.pkey, b.* FROM a LEFT JOIN b using (pkey)");
$data = pg_fetch_assoc($res);
var_dump($data['pkey']) // 实际上是 b.pkey,可能为空!
?>

两个表都包含名为 'pkey' 的列。现在表 'b' 位于 LEFT JOIN 的可选侧,因此 b.pkey(通过 'b.*' 隐式包含)可能为空。

当您使用 pg_fetch_assoc() 时,会产生问题,有两个名为 'pkey' 的列,但结果数组每个键只能包含一个值 - 在这种情况下,它将选择表 B 中的值而不是表 A 中的值,并且由于 B 位于 LEFT JOIN 的可选侧,因此 $data['pkey'] 可能会为空。因此,如果您希望检索表 A 中的列,则需要使用不同的 pg_fetch() 或重写您的查询以避免歧义。
6
Luke
18 年前
注意

设置为 TRUE 的 PostgreSQL 布尔值将返回字符串 "t"

设置为 FALSE 的 PostgreSQL 布尔值将返回字符串 "f"
2
匿名
18 年前
如果您请求一个不存在的行,它只会失败,而不是简单地返回 false。
1
ninja (whorl) thinkninja (stop) com
21 年前
如果您在不同版本的 PHP 之间迁移,这可能很方便

if (!function_exists('pg_fetch_assoc')) {
function pg_fetch_assoc ($result)
{
return @pg_fetch_array($result, NULL, PGSQL_ASSOC);
}
}
0
artem.eroshin gmail com
4 年前
将 't' 和 'f' 转换为 PHP 布尔值

$result = pg_query($_db, $sql);

while ( $row = pg_fetch_assoc( $result ) )
{
fixBooleans($result, $row);

// 其他代码
}

function fixBooleans($result, &$row)
{

for ($fld_i = 0; $fld_i < pg_num_fields($result); $fld_i++)
{
$fld_name = pg_field_name($result, $fld_i);

if( pg_field_type($result, $fld_i) == 'bool' )
{
if( $row[ $fld_name ] == 't' )
{
$row[ $fld_name ] = true;
}
elseif($row[ $fld_name ] == 'f')
{
$row[ $fld_name ] = false;
}
}
}

}
0
huntfalow at yahoo dot com
9 年前
<html>
<head>
<script>
function waarde(){
var text = document.getElementById("optVakken").value;
document.getElementById("txthidden").value = text;
document.forms["hiddenform"].submit();
}
</script>
<?php
// 带有所有教师的选项菜单
function leerkrachten($aName){
include(
"includes/connect.php");

}
// 带有所有科目的选项菜单
function vakken($aID){
include(
"includes/connect.php");
$SelectVakkenQuery = "SELECT * FROM vakken";
$SelectVakkenResult = $mysqli->query($SelectVakkenQuery);
$Choice = "<select id='$aID' onchange=waarde()><option>选择一个科目</option>";

while(
$rij2 = $SelectVakkenResult->fetch_assoc()){
$VakID = $rij2['vakid'];
$Vaknaam = $rij2['voluit'];
$Choice .= "<option value='$VakID'>$Vaknaam</option>";
}
$Choice .= "</select>";
return
$Choice;
}
?>
<title>补救练习</title>
</head>
<body>
<?php
include("includes/connect.php");
// 创建选项菜单

// 第一个选项菜单
echo vakken("optVakken")."<br><br>";

// 第二个选项菜单
if(!isset($_POST['txthidden'])){
$SelectLeerkrachtenQuery = "SELECT * FROM leerkrachten";
$SelectLeerkrachtResult = $mysqli->query($SelectLeerkrachtenQuery);

$Choice = "<select>";
while(
$rij=$SelectLeerkrachtResult->fetch_assoc()){
$Voornaam = $rij['voornaam'];
$Naam = $rij['naam'];
$LKID = $rij['leerkrachtid'];
$Volledig = $Voornaam . " " . $Naam;
$Choice .= "<option value='$LKID'>$Volledig</option>";
}
$Choice .= "</select><br><br>";
echo
$Choice;
}else{
$vakid = $_POST['txthidden'];
$SelectLeerkrachtenQuery = "SELECT * FROM leerkrachten JOIN leerkrachtpervak ON leerkrachten.leerkrachtid = leerkrachtpervak.leerkrachtid WHERE vakid = '$vakid'";
$SelectLeerkrachtResult = $mysqli->query($SelectLeerkrachtenQuery);
$Choice = "<select>";
while(
$row3=$SelectLeerkrachtResult->fetch_assoc()){
$Voornaam = $row3['voornaam'];
$Naam = $row3['naam'];
$Volledig = $Voornaam . " " . $Naam;
$Choice .= "<option>$Volledig</option>";
}
$Choice .= "</select><br><br>";
echo
$Choice;
}
// 用于JS的隐藏文本框
echo "<form method='post' id='hiddenform'><input type='hidden' name='txthidden' id='txthidden'></form>";
$mysqli->close();
?>
</body>
</html>
0
Alexey Loktionov (error at pochta dot ru)
14 年前
这是一个基于有限状态机的更强大的 pg_parse_array() 变体:适用于任何维度的 Postgres 数组(其字符串表示必须格式正确),并包含引号规则检查,复杂度为 O(N),其中 N 是 Postgres 数组的字符串表示的长度

<?php

define
('STATE_BEGIN', 1);
define('STATE_INARRAY',2);
define('STATE_OUTARRAY', 3);
define('STATE_INSLASH', 4);
define('STATE_INQUOTES', 5);

function
pg_parse_array($value) {
$resultArray = $indexArray = array(); $level = $index = 0;
$ptr = &$resultArray;
for(
$i = 0; $i < strlen($value); $i++){
switch(
$level){
case
1:
if(
$index > 0){
$ptr = & $ptr[sizeof($ptr)];
}
$indexArray[++$index] = & $ptr;
break;
case -
1:
$ptr = & $indexArray[--$index];
break;
}
$level = processFSM($value{$i}, $ptr);
}
return
$resultArray;
}

function
processFSM($chr, &$result){
static
$state = STATE_BEGIN, $index = 0;
$level = 0;
switch(
true){
case
$chr == '{' && in_array($state, array(STATE_BEGIN,STATE_INARRAY,STATE_OUTARRAY), true):
$state = STATE_INARRAY;
$index = 0;
$level = +1;
break;
case
$chr == '}' && in_array($state, array(STATE_INARRAY,STATE_OUTARRAY), true):
$state = STATE_OUTARRAY;
$level = -1;
break;
case
$chr == '\\' && $state !== STATE_BEGIN:
$state = $state === STATE_INSLASH ? STATE_INQUOTES : STATE_INSLASH;
break;

case
$chr == '"' && !in_array($state, array(STATE_BEGIN,STATE_INSLASH), true):
$state = $state === STATE_INQUOTES ? STATE_INARRAY : STATE_INQUOTES;
break;

case
$chr == ',' && in_array($state, array(STATE_INARRAY,STATE_OUTARRAY), true):
$index = sizeof($result);
break;

case
$state !== STATE_BEGIN:
$state = $state === STATE_INSLASH ? STATE_INQUOTES : $state;
isset(
$result[$index]) or $result[$index] = '';
$result[$index] .= $chr;
break;
}
return
$level;
}

?>
0
Anonymous
14 年前
请注意,如果您的结果字段是数组,它将使用“{value1,value2, ... }”的通用格式作为字符串输出,以符合 postgres 对 SQL 数组的行为。
https://postgresql.ac.cn/docs/8.4/static/arrays.html#ARRAYS-IO

因此,这里有一个函数将简单的(一维)SQL 数组转换为 PHP 数组

<?php
function pg_parse_array($field)
/*
* 将简单的 SQL 数组字段转换为其 PHP 等效项。例如:
*
* {null} --> Array(null);
* {"null"} --> Array("null");
* {foo,bar} --> Array("foo", "bar");
* {"foo,bar"} --> Array("foo,bar");
* {"Hello \"World\""} --> Array('Hello "World"');
*
*/
{
// NULL 字段始终为 NULL
if (!is_string($field)) return $field;

// 检查可能表示 SQL 数组字段的波浪号
if ($field[0] != '{' or substr($field, -1) != '}') return $field;
$field = trim(substr($field, 1, -1));

$array = Array();

// 将字符串分解为以下内容:
// - 可能包含由反斜杠转义的特殊字符的引号文本
// - 可能不包含特殊字符的未引号文本
$search = '/(")?+((?(1)(?:\\\\.|[^"])*|[^,]+))(?(1)\\1)/';
preg_match_all($search, $field, $matches, PREG_SET_ORDER);

foreach(
$matches as $value)
{
if (
$value[1])
{
// 引号元素,使用反斜杠转义字符
$array[] = preg_replace('#\\\\(.)#', '$1', $value[2]);
}
else
{
// 未引号元素
$value[2] = trim($value[2]);
if (
strtolower($value[2]) == 'null') $array[] = null; // NULL
else $array[] = $value[2];
}
}
return
$array;
}

// 一些测试以演示此功能
var_export(pg_parse_array('{null}'); // 输出是 Array(null);
var_export(pg_parse_array('{foo,bar}'); // 输出是 Array('foo', 'bar');
var_export(pg_parse_array('{"null"}'); // 输出是 Array('null');

?>
0
Anonymous
15 年前
bytea 列以转义形式返回。
您需要在它们上调用 pg-unescape-bytea() 以获取原始二进制数据。
0
Anonymous
15 年前
关于可选的 int 参数

请求结果集中不存在的行号是错误。不要这样做。

事先使用 pg_num_rows() 检查,或者只使用默认行为,该行为按顺序返回行,并在返回最后一行后返回 false。如果未返回任何行,它会立即返回 false。
0
javier dot vilarroig at gmail dot com
16 年前
值得知道的是,当您在多个表上查询时,只返回每个名称的第一行。

也就是说,如果您要将包含名为“name”的列的两个表连接起来,您将只在数组中收到一个名为“name”的字段,并且它将对应于第一个表中的那个字段。

建议在这种情况下始终给您的列起别名。
0
johniskew
17 年前
以下是一种迭代结果集并在极少代码中显示所有列的方法......可能比 foreach 更快

<?php

print '<table>';
while(
$row=pg_fetch_assoc($rs2)) print '<tr><td>'.join('</td><td>',$row2).'</td></tr>';
print
'</table>';

?>
0
petrus at bmail dot com dot au
19 年前
$dbconn3 = pg_connect("host=127.0.0.1 port=5432 dbname=blah user=blah password=blah");
$result = pg_query($dbconn3, "SELECT * FROM Packages");

echo "<HTML><HEAD><TITLE>PostgreSQL Test Page</TITLE></HEAD><BODY>";
echo "<TABLE>";

$pkg = pg_fetch_assoc($result);
foreach ($pkg as $value) {
echo "<TR><TD>$value";
echo "</TR></TD>";
}

echo "</TABLE><P>";
echo "This package's full filename is: {$pkg['name']}-{$pkg['version']}{$pkg['extension']}";
echo "</BODY></HTML>";

对于生成表格,这可行,我个人更喜欢 foreach() 而不是 while 循环,因为这样就没有意外导致无限循环的风险......foreach 只会在有东西可以处理的情况下工作,然后停止。我认为底部的 echo 可能也会派上用场......我花了一段时间才找到这个。
0
spam at pasher dot org
20 年前
需要注意的一点(截至 PHP 4.3.2)

如果您习惯使用“扩展”比较运算符(=== 和 !==)来使您的代码在视觉上更容易理解,则此函数将在提供的资源句柄无效时返回 NULL(而不是 false)。即,

$rs = @pg_query('SELECT * FROM fake_table');
while (false !== ($row = @pg_fetch_assoc($rs)))
{
print_r($row);
}

显然,您应该在开始 while 循环之前检查 $rs 是否 === false,但此示例用于说明如果 $rs 为 false,则可能出现无限循环问题。
0
Brenton Strickler
21 年前
乍一看,此页面顶部列出的语法与示例不匹配。PGSQL_ASSOC 标志不是必需的。
-3
strata_ranger at hotmail dot com
15 年前
作为对 Luke 关于 SQL 布尔值的说明的补充(这是一个令人痛苦的经验教训),一个相对简单的解决方法是在查询中将布尔值列类型转换为整数,例如

<?php
// 假设 'foo' 是一个类型为布尔值的表列
$res = pg_query("Select foo as foo1, foo::integer as foo2 from bar");

$data = pg_fetch_assoc($res);
if (
$data['foo1']) echo 'foo1 = TRUE'; // 预期效果不佳(字符串 't' 和字符串 'f' 都评估为 TRUE)
if ($data['foo2']) echo 'foo2 = TRUE'; // 预期效果良好(字符串 '0' 评估为 FALSE)
?>
To Top