【问题标题】:MySQLI Prepared Statement: num_rows & fetch_assocMySQLI 准备好的语句:num_rows & fetch_assoc
【发布时间】:2014-05-18 21:41:17
【问题描述】:

下面是一些写得不好且被严重误解的 PHP 代码,没有错误检查。老实说,我在 PHP-> MySQLi 函数的迷宫中有点挣扎!有人可以提供一个示例,说明如何使用准备好的语句在关联数组中收集结果,同时还从 $stmt 获取行数?下面的代码是我正在玩的。我认为让我失望的一点是在store_result 之后使用$stmt 值,然后尝试收集一个 assoc 数组,我不太清楚为什么......

$mysqli = mysqli_connect($config['host'], $config['user'], $config['pass'], $config['db']);
$stmt = $mysqli->prepare("SELECT * FROM licences WHERE generated = ?");
$stmt->bind_param('i', $core['id']);
$result = $stmt->execute();
$stmt->store_result();

if ($stmt->num_rows >= "1") {

    while($data = $result->fetch_assoc()){ 
        //Loop through results here $data[] 
    }

}else{

    echo "0 records found";

}

我觉得只是要求代码有点厚颜无耻,但它是我的情况的一个工作演示,我觉得我需要最终了解实际发生的情况。谢谢一百万!

【问题讨论】:

  • 对于初学者,您始终可以使用 FETCH_ALL 而不是 FETCH_ASSOC 或 FETCH_NUM,从而生成一个包含关联值和编号值的数组。其他选项:当您循环遍历结果时,只需有一个索引,在循环之前将其设置为 $i=0 ,然后执行 $i++;循环内。除此之外,我认为我并没有真正理解你的问题。我正在考虑更多,但我们将不胜感激。
  • 我目前收到错误Fatal error: Call to a member function fetch_assoc() on a non-object,我认为这是因为我的编码不正确,而不是它实际上是一个非对象,因为num_rows 实际上并没有返回 0。所以 UI 认为这部分错了$logData = $result->fetch_assoc()
  • 不,那么问题就从$result = $stmt->execute(); 部分开始。这很可能意味着 $results 实际上是一个错误,因为执行不成功。当我使用它时,这通常是因为查询错误。所有表名和列名是否正确且大小写正确?
  • 在准备和/或执行之后可能要尝试的一件事是echo $mysqli->error;
  • 嗯,我明白你的意思了。不,查询看起来很好,没有输出错误:/

标签: php mysqli prepared-statement fetch associative-array


【解决方案1】:
$result = $stmt->execute(); /* function returns a bool value */

参考:http://php.net/manual/en/mysqli-stmt.execute.php

所以写$stmt->execute(); 来执行查询就足够了。


基本思路是遵循以下顺序
1.建立联系。 (现在在使用 sqli 或 PDO 方法时,您只需一步即可连接并连接数据库)
2.准备查询模板
3. 将参数与变量绑定
4.(如果未设置或希望更改值,请设置变量的值)然后执行查询。
5. 现在获取您的数据并完成您的工作。
6. 关闭连接。


/*STEP 1*/
$mysqli = mysqli_connect($servername,$usrname,$pswd,$dbname);
/*STEP 2*/
$stmt = $mysqli->prepare("SELECT * FROM licences WHERE generated = ?");
/*Prepares the SQL query, and returns a statement handle to be used for further operations on the statement.*/
//mysqli_prepare() returns a statement object(of class mysqli_stmt) or FALSE if an error occurred.
/* STEP 3*/
$stmt->bind_param('i', $core['id']);//Binds variables to a prepared statement as parameters
/* STEP 4*/
$result = $stmt->execute();//Executes a prepared Query
/* IF you wish to count the no. of rows only then you will require the following 2 lines */
$stmt->store_result();//Transfers a result set from a prepared statement
$count=$stmt->num_rows;
/*STEP 5*/
//The best way is to bind result, its easy and sleek
while($data = $stmt->fetch()) //use fetch() fetch_assoc() is not a member of mysqli_stmt class
{ //DO what you wish
  //$data is an array, one can access the contents like $data['attributeName']
}

如果要缓冲客户端完整的结果集,必须调用mysqli_stmt_store_result() for (SELECT, SHOW, DESCRIBE, EXPLAIN),以便后续的mysqli_stmt_fetch()调用返回缓冲数据。
没有必要为其他查询调用 mysqli_stmt_store_result(),但如果你这样做,在所有情况下都不会损害或导致任何显着的性能。
--参考:php.net/manual/en/mysqli-stmt.store-result.php
http://www.w3schools.com/php/php_mysql_prepared_statements.asp
必须查看上述参考资料,他们面临着这方面的问题, 我的答案可能并不完美,欢迎大家改进我的答案...

【讨论】:

    【解决方案2】:

    您的问题是,要执行fetch->assoc(),您需要首先从准备好的语句中获取结果集:

    http://php.net/manual/en/mysqli-stmt.get-result.php

    你猜怎么着:这个函数只有在你使用 MySQL 本地驱动程序或“mysqlnd”时才有效。如果您不使用它,您将收到“致命错误”消息。

    【讨论】:

      【解决方案3】:

      您可以尝试使用 mysqli_stmt 函数 get_result() 来获取关联数组。注意 get_result 返回 mysqli_result 类型的对象。

      $stmt->execute();
      $result = $stmt->get_result(); //$result is of type mysqli_result
      $num_rows = $result->num_rows;  //count number of rows in the result
      
      // the '=' in the if statement is intentional, it will return true on success or false if it fails.
      if ($result_array = $result->fetch_assoc(MYSQLI_ASSOC)) { 
             //loop through the result_array fetching rows.
             // $ rows is an array populated with all the rows with an associative array with column names as the key 
              for($j=0;$j<$num_rows;$j++)
                  $rows[$j]=$result->fetch_row();
              var_dump($rows);
         }
      else{
         echo 'Failed to retrieve rows';
      }
      

      【讨论】:

        【解决方案4】:

        我搜索了很长时间,但从未找到正确响应所需的文档,但我进行了研究。

        $stmt-&gt;get_result() 为此目的替换 $stmt-&gt;store_result()。 所以,如果我们看到

        $stmt_result = $stmt->get_result();
        var_dump($stmt_result);
        

        我们得到

        object(mysqli_result)[3]
          public 'current_field' => int 0
          public 'field_count' => int 10
          public 'lengths' => null
          public 'num_rows' => int 8  #That we need!
          public 'type' => int 0
        

        因此,我提出以下通用解决方案。 (包括我使用的错误报告)

        #Prepare stmt or reports errors
        ($stmt = $mysqli->prepare($query)) or trigger_error($mysqli->error, E_USER_ERROR);
        
        #Execute stmt or reports errors
        $stmt->execute() or trigger_error($stmt->error, E_USER_ERROR);
        
        #Save data or reports errors
        ($stmt_result = $stmt->get_result()) or trigger_error($stmt->error, E_USER_ERROR);
        
        #Check if are rows in query
        if ($stmt_result->num_rows>0) {
        
          # Save in $row_data[] all columns of query
          while($row_data = $stmt_result->fetch_assoc()) {
            # Action to do
            echo $row_data['my_db_column_name_or_ALIAS'];
          }
        
        } else {
          # No data actions
          echo 'No data here :(';
        }
        $stmt->close();
        

        【讨论】:

        【解决方案5】:

        如果您想将 mysqli 结果收集到 PHP 中的关联数组中,您可以使用fetch_all() 方法。当然,在您尝试获取行之前,您需要使用get_result() 获取结果。 execute() 不返回任何有用的值。

        例如:

        <?php
        
        mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
        $mysqli = new mysqli($config['host'], $config['user'], $config['pass'], $config['db']);
        $mysqli->set_charset('utf8mb4'); // Don't forget to set the charset!
        
        $stmt = $mysqli->prepare("SELECT * FROM licences WHERE generated = ?");
        $stmt->bind_param('i', $core['id']);
        $stmt->execute(); // This doesn't return any useful value
        $result = $stmt->get_result();
        $data = $result->fetch_all(MYSQLI_ASSOC);
        
        if ($data) {
            foreach ($data as $row) {
                //Loop through results here
            }
        } else {
            echo "0 records found";
        }
        

        我不确定你为什么需要num_rows,你总是可以使用数组本身来检查是否有任何行。空数组在 PHP 中是错误的。

        【讨论】:

        • 毫无疑问,这是使用准备好的语句时要遵循的模板。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-27
        • 1970-01-01
        • 2012-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多