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开发者_Python百科 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.
You can do this by fetching an object instead of an array.
$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)]:''));
}
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
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 using 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. e.g. $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);
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;
}
?>
精彩评论