MySQLi 相当于 mysql_result()?
Posted
技术标签:
【中文标题】MySQLi 相当于 mysql_result()?【英文标题】:MySQLi equivalent of mysql_result()? 【发布时间】:2011-01-06 13:41:57 【问题描述】:我正在将一些旧的 php 代码从 mysql 移植到 MySQLi,但遇到了一个小问题。
没有与旧的mysql_result()
功能等效的功能吗?
我知道mysql_result()
在处理多于 1 行时比其他函数慢,但很多时候我只有 1 个结果和 1 个字段。使用它可以让我将 4 行压缩为 1。
旧代码:
if ($r && mysql_num_rows($r))
$blarg = mysql_result($r, 0, 'blah');
所需代码:
if ($r && $r->num_rows)
$blarg = $r->result(0, 'blah');
但是没有这样的事情。 :(
我有什么遗漏吗?还是我将不得不把它吸起来并做出一切:
if ($r && $r->num_rows)
$row = $r->fetch_assoc();
$blarg = $row['blah'];
【问题讨论】:
你最终在这里使用了什么?我也是这种情况 我从来没有对此做过任何事情。我只是在我需要它的罕见场合使用if ($r && $r->num_rows) $blarg = $r->result(0, 'blah');
...
谢谢,我最终使用 mysqli_query 和 mysqli_fetch_assoc 来显示结果。
【参考方案1】:
我最终使用了一个使用程序样式的自定义函数:
function mysqli_result($res, $row, $field=0)
mysqli_data_seek($res, $row);
return mysqli_fetch_array($res)[$field];
参考:https://www.sitepoint.com/community/t/change-mysql-result-to-mysqli/190972/6
【讨论】:
【参考方案2】:这是对 Mario Lurig 答案的改编,使用 mysqli_result
对象而不是 mysqli
的程序版本。
/**
* Accepts int column index or column name.
*
* @param mysqli_result $result
* @param int $row
* @param int|string $col
* @return bool
*/
function resultMysqli(mysqli_result $result,$row=0,$col=0)
//PHP7 $row can use "int" type hint in signature
$row = (int)$row; // PHP5 - cast to int
if(!is_numeric($col) ) // cast to string or int
$col = (string)$col;
else
$col = (int)$col;
$numrows = $result->num_rows;
if ($numrows && $row <= ($numrows-1) && $row >=0)
$result->data_seek($row);
$resrow = (is_numeric($col)) ? $result->fetch_row() : $result->fetch_assoc();
if (isset($resrow[$col]))
return $resrow[$col];
return false;
【讨论】:
【参考方案3】:如果您在查询中仅选择一个字段,并且您只希望所选字段的单个返回数据,那么这有效:
function mysqli_datum($result)
if ($result->num_rows == 0)
return;
$result->data_seek(0);
$row=$result->fetch_row();
return $row[0];
【讨论】:
【参考方案4】:我建议您将此行添加到 Cris' solution 以便能够同时执行 db_result('mytable.myfield)
和 db_result('myfield')
获得结果,因为它是原始 mysql_result
函数的默认行为。
function db_result($result,$row,$field)
if($result->num_rows==0) return 'unknown';
$result->data_seek($row);
$ceva=$result->fetch_assoc();
return (isset($ceva[$field])?$ceva[$field]
:(strpos($field,'.')?$ceva[substr($field,strrpos($field,'.')+1)]:''));
【讨论】:
我刚刚意识到,这只有在您的请求中只有一个名为“myfield”的字段时才有效。我有 2 个表,其中有一个名为 'myfield' 的字段 db_result('table1.myField') 和 db_result('table2.myField') 将具有相同的值,即使 db 行中的值不同。旧的 mysql_result 函数做得很好,所以它的行为并不完全相同。【参考方案5】:如果您正在寻找一个强大的库来进行数据库连接,我建议您使用AdoDB。该库可以连接多个数据库,如果您更改数据库,则无需重写查询,只要它不包含特定数据库引擎的任何特定 SQL。检查this page 以获取使用示例。另外,如果你使用 PHP5,你可以使用foreach for iteration。
我希望这将帮助您将任何旧代码转换为更健壮且跨数据库的代码。
【讨论】:
【参考方案6】:您可以通过获取对象而不是数组来做到这一点。
$mysqli->query("SELECT email FROM users WHERE userid = 'foo'")->fetch_object()->email;
您需要 PHP 5+ 才能使用这样的方法链接。
或者,如果您使用过程式 MySQLi,则可以轻松编写您自己的匹配 mysql_result
的 mysqli_result
函数。
【讨论】:
你不需要 PHP5 来做对象链接。 我自己没有尝试过在 PHP 4 中进行链接,但我确信我已经阅读了几篇关于在 PHP 4 中返回对象的差异如何使链接成为不可能的文章。 经过进一步检查,似乎是PHP4 doesn't return objects by reference, which would make method chaining impossible。有很多关于这方面的文章。 我认为没有方法链接的代码版本会很有用。特别是问题是关于从 mysql 移植到 mysqli 而不是 PHP4 到 5。【参考方案7】:我用下面的函数代替mysql_result()
function mysqli_result($result, $iRow, $field = 0)
if(!mysqli_data_seek($result, $iRow))
return false;
if(!($row = mysqli_fetch_array($result)))
return false;
if(!array_key_exists($field, $row))
return false;
return $row[$field];
【讨论】:
【参考方案8】:虽然回答了,但我认为在遇到相同问题后我可以改进给出的答案。以下函数完全复制了 mysql_result() 函数,并在您的请求越界时返回 false(空结果,没有该数字的行,没有该数字的列)。它确实有一个额外的好处,如果您不指定行,它会假定为 0,0(要传递的值少一个)。该函数已更新为允许字段或字段名称的数字偏移。
function mysqli_result($res,$row=0,$col=0)
$numrows = mysqli_num_rows($res);
if ($numrows && $row <= ($numrows-1) && $row >=0)
mysqli_data_seek($res,$row);
$resrow = (is_numeric($col)) ? mysqli_fetch_row($res) : mysqli_fetch_assoc($res);
if (isset($resrow[$col]))
return $resrow[$col];
return false;
【讨论】:
与其调用 mysqli_num_rows() 两次,不如改为:mysqli_num_rows($res) > $row) 为了减少调用,可以调整如下: $numrows = myqsli_num_rows($res); if ($numrows && $row =0) 注意到这是漫长的一天...但是如果 myqsli_num_rows() 返回 0,那么if (mysqli_num_rows($result) > $row) ...
,您需要检查的不就是这些吗?...假设您不会通过在 $row = -1... 或返回 5 行的相反结果...如果您要求第 0 行小于 5(给您第一个记录),要求第 4 行也很好(给您最后记录),请求第 5 行或第 6 行失败(5 或 6 不小于 5)。
Craig,你是对的,但由于它是 mysql_result() 的功能替代品,我不想假设没有用户错误 ($row=-1)。但是是的,将其简化为: if ($row >= 0 && mysqli_num_rows($res) > $row)
功能已更新。以前,$col 必须是数字偏移量。现在,它也接受字段名称。【参考方案9】:
这是一个很好的答案,来自http://php.net/manual/es/class.mysqli-result.php
<?php
function mysqli_result($result,$row,$field=0)
if ($result===false) return false;
if ($row>=mysqli_num_rows($result)) return false;
if (is_string($field) && !(strpos($field,".")===false))
$t_field=explode(".",$field);
$field=-1;
$t_fields=mysqli_fetch_fields($result);
for ($id=0;$id<mysqli_num_fields($result);$id++)
if ($t_fields[$id]->table==$t_field[0] && $t_fields[$id]->name==$t_field[1])
$field=$id;
break;
if ($field==-1) return false;
mysqli_data_seek($result,$row);
$line=mysqli_fetch_array($result);
return isset($line[$field])?$line[$field]:false;
?>
【讨论】:
这可能不是关于性能的最佳解决方案,但它是使用表名作为每个查询字段的前缀的查询的唯一有效答案,+1。【参考方案10】:PHP 5.4 现在支持function array dereferencing,这意味着您可以这样做:
if ($r && $r->num_rows)
$row = $r->fetch_assoc()['blah'];
【讨论】:
【参考方案11】:function db_result($result,$row,$field)
if($result->num_rows==0) return 'unknown';
$result->data_seek($row);
$ceva=$result->fetch_assoc();
$rasp=$ceva[$field];
return $rasp;
【讨论】:
【参考方案12】:嗯,你总是可以把它缩短成这样的:
if ($r && $r->num_rows)
list($blarg) = $r->fetch_row();
但这可能与您将获得的一样好。
【讨论】:
以上是关于MySQLi 相当于 mysql_result()?的主要内容,如果未能解决你的问题,请参考以下文章