【问题标题】:MySQLi equivalent of mysql_result()?MySQLi 相当于 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 来显示结果。

标签: php mysqli


【解决方案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_resultmysqli_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) &gt; $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();
                

                但这可能与您将获得的一样好。

                【讨论】:

                  猜你喜欢
                  • 2014-04-03
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-07-25
                  • 2020-02-19
                  • 2016-08-12
                  • 2016-08-09
                  相关资源
                  最近更新 更多