简体   繁体   中英

MySQLi equivalent of mysql_result()?

I'm porting some old PHP code from mysql to MySQLi, and I've ran into a minor snag.

Is there no equivalent to the old 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. Using it lets me condense 4 lines into 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). It does have the added benefit that, if you don't specify the row, it assumes 0,0 (one less value to be passed). 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:

$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.

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

$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.

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.

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() .

$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. eg $data[1][2] ?? null; $data[1][2] ?? null; .

As of PHP 8.1, mysqli also offers method called 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()

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

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 .

/**
 * 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

<?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 . 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. Check this page for a usage sample. Also, if you using PHP5, you can useforeach for iteration .

I hope this will help you convert any old codes to a more robust and cross database code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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