mysql_fetch_assoc

(PHP 4 >= 4.0.3, PHP 5)

mysql_fetch_assoc将结果行作为关联数组获取

警告

此扩展在 PHP 5.5.0 中已弃用,并在 PHP 7.0.0 中移除。应改用 MySQLiPDO_MySQL 扩展。另请参阅 MySQL:选择 API 指南。此函数的替代方法包括

描述

mysql_fetch_assoc(resource $result): array

返回一个与获取的行相对应的关联数组,并向前移动内部数据指针。mysql_fetch_assoc() 等同于调用 mysql_fetch_array(),其中可选的第二个参数为 MYSQL_ASSOC。它只返回关联数组。

参数

result

要评估的结果 resource。此结果来自对 mysql_query() 的调用。

返回值

返回一个与获取的行相对应的字符串关联数组,如果不再有行,则返回 false

如果结果中的两个或多个列具有相同的字段名称,则最后一个列将优先。要访问相同名称的其他列,您需要使用 mysql_fetch_row() 使用数字索引访问结果,或者添加别名。有关别名的信息,请参阅 mysql_fetch_array() 说明中的示例。

示例

示例 #1 一个扩展的 mysql_fetch_assoc() 示例

<?php

$conn
= mysql_connect("localhost", "mysql_user", "mysql_password");

if (!
$conn) {
echo
"无法连接到数据库: " . mysql_error();
exit;
}

if (!
mysql_select_db("mydbname")) {
echo
"无法选择 mydbname: " . mysql_error();
exit;
}

$sql = "SELECT id as userid, fullname, userstatus
FROM sometable
WHERE userstatus = 1"
;

$result = mysql_query($sql);

if (!
$result) {
echo
"无法成功从数据库运行查询 ($sql): " . mysql_error();
exit;
}

if (
mysql_num_rows($result) == 0) {
echo
"未找到行,无内容可打印,因此退出";
exit;
}

// 当存在数据行时,将该行作为关联数组放入 $row 中
// 注意:如果您只期望一行,则无需使用循环
// 注意:如果您在以下循环中放置 extract($row);,那么您将
// 创建 $userid、$fullname 和 $userstatus
while ($row = mysql_fetch_assoc($result)) {
echo
$row["userid"];
echo
$row["fullname"];
echo
$row["userstatus"];
}

mysql_free_result($result);

?>

注释

注意: 性能

需要注意的重要一点是,使用 mysql_fetch_assoc() 并不显著地 比使用 mysql_fetch_row() 慢,同时它提供了显著的附加价值。

注意: 此函数返回的字段名称是区分大小写的。

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

参见

添加注释

用户贡献的注释 15 个注释

5
marREtijn dot posthMOuma at hoVEme dot nl
20 年前
看来您不能在结果数组中使用 table.field 名称。
如果您的结果为空,并且您使用的是多表查询,只需使用别名即可

$res=mysql_query("SELECT user.ID AS uID, order.ID AS oID FROM user, order WHERE ( order.userid=uID )";
while ($row=mysql_fetch_assoc($res)) {
echo "<p>userid: $row['uID'], orderid: $row['oID']</p>";
}
4
joe at kybert dot com
19 年前
值得指出的是,在收集当前行的​​数据后,内部行指针会递增一次。

这意味着多次调用将遍历行数据,因此您无需在调用之间使用 mysql_data_seek(..)。

这在 mysql_fetch_row() 文档中有所说明,但在这里没有!?
-1
Typer85 at gmail dot com
17 年前
请注意,您传递给此函数的资源结果可以被认为是通过引用传递的,因为资源只是一个指向内存位置的指针。

因此,您不能在同一个脚本中两次遍历资源结果,除非将指针重置回起始位置。

例如

----------------
<?php

// 假设我们已经查询了数据库。

// 循环遍历结果集。

while( $queryContent = mysql_fetch_row( $queryResult ) {

// 显示。

echo $queryContent[ 0 ];
}

// 我们已经循环遍历了资源结果,因此指针不再指向任何行。

// 如果我们决定再次循环遍历相同的资源结果
//,该函数将始终返回 false,因为它
// 将假定没有更多行。

// 因此,以下代码,如果在之前的代码之后执行
// 段将不起作用。

while( $queryContent = mysql_fetch_row( $queryResult ) {

// 显示。

echo $queryContent[ 0 ];
}

// 因为 $queryContent 现在等于 FALSE,循环
// 将不会被执行。

?>
----------------

解决这个问题的唯一方法是将指针重置,使其再次指向第一行,因此现在完整的代码如下

----------------
<?php

// 假设我们已经查询了数据库。

// 循环遍历结果集。

while( $queryContent = mysql_fetch_row( $queryResult ) {

// 显示。

echo $queryContent[ 0 ];
}

// 重置我们的指针。

mysql_data_seek( $queryResult );

// 再次循环。

while( $queryContent = mysql_fetch_row( $queryResult ) {

// 显示。

echo $queryContent[ 0 ];
}

?>
----------------

当然,您需要进行额外的检查以确保结果中的行数不为 0,否则 mysql_data_seek 本身将返回 false 并引发错误。

另外请注意,这适用于所有获取结果集的函数,包括 mysql_fetch_row、mysql_fetch_assos 和 mysql_fetch_array。
-4
george at georgefisher dot com
15 年前
感谢 R. Bradley 的 implode 想法。以下修复了一些错误,并包含 quote_smart 功能(并且已通过测试)

<?php
function mysql_insert_assoc ($my_table, $my_array) {

//
// 将值插入 MySQL 数据库
// 包含 quote_smart 代码以阻止 SQL 注入
//
// 对该函数的调用:
//
// $val1 = "foobar";
// $val2 = 495;
// mysql_insert_assoc("tablename", array(col1=>$val1, col2=>$val2, col3=>"val3", col4=>720, col5=>834.987));
//
// 发送以下查询:
// INSERT INTO 'tablename' (col1, col2, col3, col4, col5) values ('foobar', 495, 'val3', 720, 834.987)
//

global $db_link;

// 从数组 $my_array 中查找所有键(列名)
$columns = array_keys($my_array);

// 从数组 $my_array 中查找所有值
$values = array_values($my_array);

// quote_smart 值
$values_number = count($values);
for (
$i = 0; $i < $values_number; $i++)
{
$value = $values[$i];
if (
get_magic_quotes_gpc()) { $value = stripslashes($value); }
if (!
is_numeric($value)) { $value = "'" . mysql_real_escape_string($value, $db_link) . "'"; }
$values[$i] = $value;
}

// 组成查询
$sql = "INSERT INTO $my_table ";

// 创建以逗号分隔的列名字符串,并用括号括起来
$sql .= "(" . implode(", ", $columns) . ")";
$sql .= " values ";

// 创建以逗号分隔的值字符串,并用括号括起来
$sql .= "(" . implode(", ", $values) . ")";

$result = @mysql_query ($sql) OR die ("<br />\n<span style=\"color:red\">Query: $sql UNsuccessful :</span> " . mysql_error() . "\n<br />");

return (
$result) ? true : false;
}
?>
-5
benlanc at ster dot me dot uk
18 年前
可能不言而喻,但使用 list() 与 mysql_fetch_assoc() 结合使用不起作用 - 请改为使用 mysql_fetch_row()。

<?php
$sql
= "SELECT `id`,`field`,`value` FROM `table`";
$result = mysql_query($sql);

// 这将导致 rowID、fieldName、myValue 的值为空
list($rowID,$fieldName,$myValue) = mysql_fetch_assoc($result);

// 这是您想要的:
list($rowID,$fieldName,$myValue) = mysql_fetch_row($result);
?>
-5
R. Bradley
17 年前
针对 Sergiu 的函数 - implode() 会让事情变得更轻松 ... 如下所示

<?php
function mysql_insert_assoc ($my_table, $my_array) {

// 从数组 $my_array 中查找所有键(列名)
$columns = array_keys($my_array);

// 从数组中查找所有值
$values = array_values($my_array);

// 我们组成查询
$sql = "insert into `$my_table` ";
// 将列名连接在一起,在每个列名之间插入 "\", \""(但最后一个列名除外)
// 我们同时添加封闭引号
$sql .= "(\"" . implode("\", \"", $column_names) . "\")";
$sql .= " values ";
// 与值相同
$sql .= "(" . implode(", ", $values) . ")";

$result = mysql_query($sql);

if (
$result)
{
echo
"该行已成功添加";
return
true;
}
else
{
echo (
"该行未添加<br>错误是" . mysql_error());
return
false;
}
}
?>

因此,对该函数的调用为
mysql_insert_assoc("tablename", array("col1"=>"val1", "col2"=>"val2"));

将以下 sql 查询发送到 mysql
INSERT INTO `tablename` ("col1", "col2") VALUES ("val1", "val2")
-7
jono
18 年前
请注意,$row[] 中引用的字段名称区分大小写,而许多 sql 命令不区分大小写。
-9
Daniel Chcouri - 333222 +A-T+ gmail
15 年前
将所有结果获取到数组中,使用单行代码

<?php
$result
= mysql_query(...);
while((
$resultArray[] = mysql_fetch_assoc($result)) || array_pop($resultArray));
?>
-7
jo at durchholz dot org
19 年前
总结 moverton at northshropshiredc dot gov dot uk 和 Olivier Fabre 的观点

如果查询是“SELECT something1, something2, .... FROM tbl WHERE some_condition”,则返回数组中的键将是'something1','something2'等。*即使对于那些不只是字段名的“something”*。

非字段名“something”的示例包括:
NULL
NOW
MAX(some_fieldname)

我还没有测试这是否适用于table.fieldname,但我看不出为什么不适用(如果我没有得到预期的结果,我会怀疑我的代码中有错误;我肯定也有过很多这样的错误!)

我发现通过简单地对结果行进行var_dump,像这样来检查错别字是最方便的:

<?php
echo '<pre>Got this row:'
var_dump ($row);
echo
'</pre>';
?>

其中$row是来自上次调用mysql_fetch_assoc的结果。
-7
josh at joshstrike dot com
15 年前
这里有一个巧妙的函数,可以将整个表格复制到另一个表格。它接受以下参数:
$z -> 一个SQL查询的结果,其列与你要复制到的表格匹配。
$toTable -> 要复制到的表格的字符串名称。
$link_identifier -> 要复制到的表格的数据库资源。
如果有人能找到更快的执行此操作的方法,我很乐意知道...

<?php
function mysql_multirow_copy($z,$toTable,$link_identifier) {
$fields = "";
for (
$i=0;$i<mysql_num_fields($z);$i++) {
if (
$i>0) {
$fields .= ",";
}
$fields .= mysql_field_name($z,$i);
}
$q = "INSERT INTO $toTable ($fields) VALUES";
$c = 0;
mysql_data_seek($z,0); //critical reset in case $z has been parsed beforehand. !
while ($a = mysql_fetch_assoc($z)) {
foreach (
$a as $as) {
$a[key($a)] = addslashes($as);
next ($a);
}
if (
$c>0) {
$q .= ",";
}
$q .= "('".implode(array_values($a),"','")."')";
$c++;
}
$q .= ";";
$z = mysql_query($q,$link_identifier);
return (
$q);
}
?>
-7
moverton at northshropshiredc dot gov dot uk
19 年前
实际上,Olivier,你完全错了,因为你的示例代码中有一个错误。它确实会返回 $row['MAX(time)'] - 你必须将 MySQL 资源传递给 mysql_fetch_assoc(),而你没有这样做。这是:

$row = mysql_fetch_assoc($conn)

...其中 $conn 是你的数据库连接,实际上会产生一个结果。下面的完整示例取自我自己编写的 内容管理系统

$query = 'SELECT MAX(ctRevDate) FROM content group by ctPage';
$querySet = mysql_query($query, $conn);
$row = mysql_fetch_assoc($querySet);
print_r($row);

这会产生:

Array
(
[MAX(ctRevDate)] => 2004-01-15
)

..在我的测试台上。所以实际上它根本不需要别名。
-8
chasfileDELETE_ALL_CAPS at gmail dot com
18 年前
如果你想要一个二维数组呢?例如,这对于作为 HTML 表格输出很有用。

function mysql_resultTo2DAssocArray ( $result) {
$i=0;
$ret = array();
while ($row = mysql_fetch_assoc($result)) {
foreach ($row as $key => $value) {
$ret[$i][$key] = $value;
}
$i++;
}
return ($ret);
}

print_r(mysql_resultTo2DAssocArray(mysql_query("SELECT * FROM something")));

Array ( [0] => Array ( [symbol] => ARNA
[datetime] => 2006-02-17 16:00:00
[price] => 16.83 )
[1] => Array ( [symbol] => CALP
[datetime] => 2006-02-17 16:00:00
[price] => 6.54 )
[2] => Array ( [symbol] => CROX
[datetime] => 2006-02-17 16:00:00
[price] => 27.4 ))
-9
erik[at]phpcastle.com
19 年前
当你必须多次循环遍历查询的结果时,你可以使用 mysql_data_seek () 将结果指针设置为 0(零)。

这样做的优点是你不必用同一个查询两次查询数据库:)

所以:
<?php
$query
= "
SELECT *
FROM database
"
;

//Query database
$result = mysql_query ($query);

//Iterate result
while ($record = mysql_fetch_assoc ($result)){
print_r ($record);
}

...

//Point to 0 (zero)
mysql_data_seek ($result, 0);

//Re-use the result
while ($record = mysql_fetch_assoc ($result)){
print_r ($record);
}
?>
-10
nick at homefeedback dot com
17 年前
function array2table: 对下面帖子的一个小修复,处理从 mysql 返回的 null 或 0 的数据...

这是一个将 MySQL 结果显示在 HTML 表格中的有用脚本。

<?

function array2table($arr,$width)
{
$count = count($arr);
if($count > 0){
reset($arr);
$num = count(current($arr));
echo "<table align=\"center\" border=\"1\"cellpadding=\"5\" cellspacing=\"0\" width=\"$width\">\n";
echo "<tr>\n";
foreach(current($arr) as $key => $value){
echo "<th>";
echo $key."&nbsp;";
echo "</th>\n";
}
echo "</tr>\n";
while ($curr_row = current($arr)) {
echo "<tr>\n";
$col = 1;
while (false !== ($curr_field = current($curr_row))) {
echo "<td>";
echo $curr_field."&nbsp;";
echo "</td>\n";
next($curr_row);
$col++;
}
while($col <= $num){
echo "<td>&nbsp;</td>\n";
$col++;
}
echo "</tr>\n";
next($arr);
}
echo "</table>\n";
}
}

?>

<?

// Add DB connection script here

$query = "SELECT * FROM mytable";
$result = mysql_query($query);
while($row = mysql_fetch_assoc($result)){
$array[] = $row; }

array2table($array,600); // Will output a table of 600px width

?>
-14
bkfake-php at yahoo dot com
10 年前
虽然从 PHP 5.5 开始被弃用,但 mySQL 函数不会触发 E_DEPRECATED 错误
To Top