MySQLI Prepared Statement:num_rows& FETCH_ASSOC

时间:2014-04-06 19:38:53

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

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

$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";

}

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

6 个答案:

答案 0 :(得分:8)

我搜索了很长时间但从未找到需要正确回复的文档,但我做了我的研究。

$stmt->get_result()为此目的替换$stmt->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();

答案 1 :(得分:2)

$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']
}

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

答案 2 :(得分:2)

你的问题是要做fetch->assoc(),你需要先使用以下方法从预备语句中获取结果集:

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

猜猜看:只有在使用MySQL本机驱动程序或" mysqlnd"时,此功能才有效。如果你没有使用它,你将得到"致命错误"消息。

答案 3 :(得分:1)

您可以使用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 :(得分:0)

如果您想将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中是假的。

答案 5 :(得分:-3)

是的,数据库函数有点奇怪。你会到达那里。

代码看起来有些不确定,但是它是如何运作的:

建立连接,准备语句,绑定参数并执行它,一切都很好。

$result = $stmt->execute(); //execute() tries to fetch a result set. Returns true on succes, false on failure.
$stmt->store_result(); //store_result() "binds" the last given answer to the statement-object for... reasons. Now we can use it!

if ($stmt->num_rows >= "1") { //Uses the stored result and counts the rows.

  while($data = $result->fetch_assoc()){ 
        //And here, the answer-object is turned into an array-(object)
        // which can be worked with nicely.
        //It loops trough all entries in the array.
  }

}else{

   echo "0 records found";
}