web-dev-qa-db-ja.com

MySQLI準備済みステートメント:num_rows&fetch_assoc

以下は、よく書かれておらず、誤解されているPHPエラーチェックのないコードです。正直に言うと、PHP-> MySQLi関数の迷路に頭を悩ませるのに少し苦労しています! $ stmtから行数を取得しながら、準備済みステートメントを使用して連想配列の結果を収集する方法の例を示しますか?以下のコードは私が試してみているものです。私をスローしているビットは$stmtを使用していると思いますstore_resultの後に値を指定してから、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";

}

コードを要求するだけで少し生意気に感じますが、実際に何が起こっているのかを最終的に理解する必要があると感じる、私の状況の実際のデモです。どうもありがとう!

8
Arbiter

長い間検索を行いましたが、正しく応答するために必要なドキュメントは見つかりませんでしたが、調査を行いました。

$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();
9
Blaztix

ここでの問題は、fetch->assoc()を実行するために、準備されたステートメントから最初に結果セットを取得する必要があることです。

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

そして、この関数は、MySQLネイティブドライバーまたは「mysqlnd」を使用している場合にのみ機能します。使用していない場合は、「致命的なエラー」メッセージが表示されます。

2
PaulJ
_$result = $stmt->execute(); /* function returns a bool value */
_

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

そのため、クエリ実行のために$stmt->execute();を記述するだけで十分です。


基本的な考え方は、次のsequenceに従うことです。
1。接続します。 (今、sqliまたはPDOメソッドを使用している間は、データベースに接続して1つのステップで接続します)
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()を呼び出す必要はありませんが、そうした場合でも、すべてのケースで悪影響を及ぼしたり、顕著なパフォーマンスを引き起こしたりすることはありません。
-参照:php.net/manual/en/mysqli-stmt.store-result.php
および http://www.w3schools.com/php/php_mysql_prepared_statements.asp
これに関して問題に直面している上記の参照を調べる必要があります。私の答えは完全ではない可能性があります。人々は私の答えを改善することを歓迎します...

2
Feroz Ahmad

関連する配列をフェッチするために使用できる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';
}
1
yovsky