简体   繁体   English

MySQLi 等效于 mysql_result()?

[英]MySQLi equivalent of mysql_result()?

I'm porting some old PHP code from mysql to MySQLi, and I've ran into a minor snag.我正在将一些旧的 PHP 代码从 mysql 移植到 MySQLi,我遇到了一个小问题。

Is there no equivalent to the old mysql_result() function?有没有等效于旧的mysql_result() function?

I know mysql_result() is slower than the other functions when you're working with more than 1 row, but a lot of the time I have only 1 result and 1 field.我知道mysql_result()在处理超过 1 行时比其他函数慢,但很多时候我只有 1 个结果和 1 个字段。 Using it lets me condense 4 lines into 1.使用它可以让我将 4 行压缩为 1。

Old code:旧代码:

if ($r && mysql_num_rows($r))  
    $blarg = mysql_result($r, 0, 'blah');

Desired code:所需代码:

if ($r && $r->num_rows)  
    $blarg = $r->result(0, 'blah');

But there is no such thing.但是没有这样的事情。 :( :(

Is there something I'm missing?有什么我想念的吗? Or am I going to have to suck it up and make everything:或者我将不得不把它吸起来并做出一切:

if ($r && $r->num_rows)  
{  
    $row = $r->fetch_assoc();  
    $blarg = $row['blah'];  
}

The following function fully replicates the mysql_result() function, and returns false when you are out-of-bounds on your request (empty result, no row of that number, no column of that number).以下函数完全复制了mysql_result()函数,并在您的请求越界时返回false (空结果,没有该数字的行,没有该数字的列)。 It does have the added benefit that, if you don't specify the row, it assumes 0,0 (one less value to be passed).它确实有一个额外的好处,如果您不指定行,它会假定为 0,0(要传递的值少一个)。 The function allows for the numerical offset of the field or the field name.该函数允许字段或字段名称的数字偏移量。

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;
}

PHP 5.4 now supports function array dereferencing and 7.0 supports a null coalescing operator , which means you can simply do this: PHP 5.4 现在支持函数数组解引用,而 7.0 支持空合并运算符,这意味着您可以简单地这样做:

$value = $r->fetch_assoc()['blah'] ?? false;  

or even more generic variant where you don't need to supply the column name,甚至更通用的变体,您不需要提供列名,

$value = $r->fetch_row()[0] ?? false;  

note that you don't even need the if ($r && $r->num_rows) condition.请注意,您甚至不需要if ($r && $r->num_rows)条件。

您可以通过获取对象而不是数组来做到这一点。

$mysqli->query("SELECT email FROM users WHERE userid = 'foo'")->fetch_object()->email;
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; 
}

Well, you can always shorten it to something like this:好吧,你总是可以把它缩短成这样的:

if ($r && $r->num_rows)
    list($blarg) = $r->fetch_row();

But that might be as good as you're going to get.但这可能与您将获得的一样好。

I suggest you to add this line to Cris' solution in order to be able to get a result by both doing db_result('mytable.myfield) and db_result('myfield') since it is the default behavior of the original mysql_result function.我建议您将此行添加到Cris 的解决方案中,以便能够通过执行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)]:'')); 
}

You don't need mysql_result() or any similar function.您不需要mysql_result()或任何类似的功能。

If you would like to access any column from any row in the result set, the best way is to fetch all into an array usingmysqli_fetch_all() .如果您想从结果集中的任何行访问任何列,最好的方法是使用mysqli_fetch_all()将所有内容提取到数组中。

$data = $result->fetch_all(MYSQLI_BOTH);
$var1 = $data[0]['column']; // column from the first row
$var2 = $data[1][2]; // third column from the second row

To prevent access to non-existent values, you can use the null-coalesce operator and provide default value.为了防止访问不存在的值,您可以使用 null-coalesce 运算符并提供默认值。 eg $data[1][2] ?? null;例如$data[1][2] ?? null; $data[1][2] ?? null; . .

As of PHP 8.1, mysqli also offers method called fetch_column() .从 PHP 8.1 开始,mysqli 还提供了名为fetch_column()的方法。 You can use it if you only want to fetch a single value from the result.如果您只想从结果中获取单个值,则可以使用它。

$value = $mysqli->query("SELECT email FROM users WHERE userid = 'foo'")->fetch_column(0);

I use the following function to replace mysql_result()我使用以下函数替换 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];
}

I ended up using a custom function using procedural style:我最终使用了一个使用程序样式的自定义函数:

function mysqli_result($res, $row, $field=0) {
    mysqli_data_seek($res, $row);
    return mysqli_fetch_array($res)[$field];
}

Reference: https://www.sitepoint.com/community/t/change-mysql-result-to-mysqli/190972/6参考: https ://www.sitepoint.com/community/t/change-mysql-result-to-mysqli/190972/6

If you select only ONE field in the query and you only expect a single returned data of a selected field, then this works:如果您在查询中仅选择一个字段并且您只期望所选字段的单个返回数据,那么这有效:

function mysqli_datum($result)
{
    if ($result->num_rows == 0)
        return;
    $result->data_seek(0);
    $row=$result->fetch_row();     
    return $row[0];
}

Here's an adaptation of Mario Lurig's answer using a mysqli_result object instead of the procedural version of mysqli .这是对 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;
}

This is a good answer, from http://php.net/manual/es/class.mysqli-result.php这是一个很好的答案,来自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;
}
?>

If you are looking for a robust library to do database connection, I suggest you use AdoDB .如果您正在寻找一个强大的库来进行数据库连接,我建议您使用AdoDB This library can connect to multiple database, and you don't have to rewrite your query if you change the database, as long as it doesn't contain any specific SQL for a certain database engine.该库可以连接多个数据库,如果您更改数据库,则无需重写查询,只要它不包含特定数据库引擎的任何特定 SQL。 Check this page for a usage sample.检查此页面以获取使用示例。 Also, if you using PHP5, you can useforeach for iteration .此外,如果您使用 PHP5,则可以使用foreach 进行迭代

I hope this will help you convert any old codes to a more robust and cross database code.我希望这将帮助您将任何旧代码转换为更健壮和跨数据库的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM