PHPにおけるMySQLi拡張学習(五)MySQLI_STMTオブジェクト操作

6305 ワード

PDOのPDOのようにStatementオブジェクトと同様、MySQLI_STMTオブジェクトは、MySQLiによって生成された前処理文を操作するために使用される前処理文によって形成されたオブジェクトでもある.操作方法なども似ていますが、バインドパラメータを主とするSQL文や結果セットを取得する操作もあります.
パラメータバインドおよび操作プロパティ
以前の記事では、私たちが使っているbind_を見たことがあると思います.PDOにおけるbindParam()法とは大きく異なるparam()法.
$stmt = $mysqli->prepare("insert into zyblog_test_user(username, password, salt) values(?, ?, ?)");

$username='mysqli_username';
$password='mysqli_password';
$salt = 'mysqli_salt';
$stmt->bind_param('sss', $username, $password, $salt);

var_dump($stmt->insert_id); // int(232)
var_dump($stmt->affected_rows); // int(1)

$stmt->execute();

$stmt->close();

まず前に述べたようにMySQLI_STMTでバインドパラメータは使用できますか?疑問符プレースホルダ、bind_を使用param()の場合、パラメータを順番にバインドするために's'というものを使用します.この's'は文字列を表します.また、「i」は整数値を表し、「d」は浮動小数点数を表し、「b」はblobタイプを表すこともできる.
また、上記のテストコードからもbind_を1つ使用できることがわかります.param()メソッドは複数のパラメータをバインドし,'sss'は3つの文字列であり,順次バインドする.
パラメータをバインドすると、execute()メソッドで文を実行できます.PDOと同様に,この方法は成功に失敗した情報,すなわちブール値のみを返す.だから私たちはMySQLIを通過する必要がありますSTMTオブジェクトのinsert_idは、新たに追加されたデータのIDを取得するか、affected_rowsプロパティは、現在の文の実行後に影響するロー数を取得し、文が本当に実行され、私たちの期待に達しているかどうかを決定します.
最後に、close()を使用して現在のSTMTオブジェクトを閉じます.これにより、後の操作で上の$stmtオブジェクトが使用できなくなります.
次に、間違ったタイプをバインドしたらどうなるか、MySQLI_を見てみましょう.STMTでエラーメッセージについてのヒント.
$stmt = $mysqli->prepare("insert into zyblog_test_user(id, username, password, salt) values(?, ?, ?, ?)");

$id = 's';
$username='mysqli_username';
$password='mysqli_password';
$salt = 'mysqli_salt';
$stmt->bind_param('isss', $username, $password, $salt);
$stmt->execute();


var_dump($stmt->errno); // int(2031)
var_dump($stmt->error); // string(53) "No data supplied for parameters in prepared statement"
var_dump($stmt->error_list);
// array(1) {
//     [0]=>
//     array(3) {
//       ["errno"]=>
//       int(2031)
//       ["sqlstate"]=>
//       string(5) "HY000"
//       ["error"]=>
//       string(53) "No data supplied for parameters in prepared statement"
//     }
//   }

$stmt->close();

コードではidパラメータのバインドを追加し、指定したタイプは'i'ですが、実際に渡された変数は文字列タイプであり、結果としてMySQLI_STMTにエラーが発生しました.
MySQLI_STMTのエラー属性と情報は基本的にMySQLiオブジェクトと同じです.
列のバインド
クエリ文パラメータのバインディングを要求するほか、MySQLI_STMTも直接バインドカラムをサポートしています.PDOのbindColumn()と同じです.
$stmt = $mysqli->prepare("select * from zyblog_test_user where username = ?");

$username = 'kkk';
$stmt->bind_param("s", $username); //     
$stmt->bind_result($col1, $col2, $col3, $col4);
$stmt->execute(); //     

var_dump($stmt);
// object(mysqli_stmt)#2 (10) {
//     ["affected_rows"]=>
//     int(-1)
//     ["insert_id"]=>
//     int(0)
//     ["num_rows"]=>
//     int(0)
//     ["param_count"]=>
//     int(1)
//     ["field_count"]=>
//     int(4)
//     ["errno"]=>
//     int(0)
//     ["error"]=>
//     string(0) ""
//     ["error_list"]=>
//     array(0) {
//     }
//     ["sqlstate"]=>
//     string(5) "00000"
//     ["id"]=>
//     int(3)
//   }

while($stmt->fetch()){
    printf("%s %s %s %s", $col1, $col2, $col3, $col4);
    echo PHP_EOL;
}
// 42 kkk 666 k6
// 43 kkk 666 k6
// ……

var_dump($stmt->num_rows); // int(7)

$stmt->close();

もちろん、メソッドの名前は少し変更されています.MySQLI_STMTでカラムをバインドする方法名はbind_result()は、名前が違いますが、機能はほとんど悪くありません.クエリー文にはいくつかのカラム名があり、いくつかのカラム名をバインドします.このテーブルには4つのフィールドがあるので、参照伝達によって4つのカラム変数をバインドします.fetch()を使用してクエリー結果オブジェクトの遍歴を行う場合は、参照を使用して4つのカラム変数に値を割り当てるようにします.
このコードではnum_を使用しています.rowsという属性は、SELECT文のみを対象としたクエリ結果のロー数を取得します.上で紹介したaffected_rowsは影響を受ける行数で、この2つの属性は同じ概念ではありませんよ!
結果セットを返す
fetch()メソッドを実行すると、結果セットを指定した変数にバインドすることが主な役割を果たすブール値が返されます.したがって、結果を直接印刷しても役に立つ情報はありません.カラム変数をバインドすることでデータを取得する必要があります.実際に結果セットを取得したデータは、別の方法でMySQLI_を取得します.resultオブジェクト、そしてこのオブジェクトの中の方法を使えばPDOのfetch()のように本当の結果セットを得ることができます.
$stmt = $mysqli->prepare("select * from zyblog_test_user where username = 'kkk'");

$stmt->execute(); //     
$result = $stmt->get_result();


while($row = $result->fetch_assoc()){
    var_dump($row);
}
// array(4) {
//     ["id"]=>
//     int(42)
//     ["username"]=>
//     string(3) "kkk"
//     ["password"]=>
//     string(3) "666"
//     ["salt"]=>
//     string(2) "k6"
//   }
// ……

$stmt->close();

ここではget_result()メソッドは、結果セットのMySQLI_を取得しました.resultオブジェクト.その後、オブジェクトのfetch_を通過します.assoc()はキー名形式の結果セット配列を得た.
MySQLI_についてresultオブジェクトの内容は,次の文章でさらに詳細な学習理解を行う.
結果セットとカーソル移動の保存
最後にカーソルの移動についてです.上のテストデータでは7つのデータをクエリーできます.最初のデータのidは42です.カーソルでは、SQL文でlimitを使用せずに結果セットを直接操作して必要なデータを取得できます.
$stmt = $mysqli->prepare("select * from zyblog_test_user where username = 'kkk'");

$stmt->bind_result($col1, $col2, $col3, $col4);
$stmt->execute(); //     
$stmt->store_result();
//   7 ,  5   
$stmt->data_seek(5);
$stmt->fetch();
printf("%s %s %s %s", $col1, $col2, $col3, $col4); // 47 kkk 666 k6
echo PHP_EOL;

$stmt->close();

まずstoreを使う必要がありますresult()メソッドは、結果セットをメモリに保存します.このメソッドとMySQLiのstore_result()メソッドは同じです.そして、data_でseek()メソッドはカーソルを5つの位置に移動し,最後に出力した結果,後の2つのデータの内容となる.とても高い感じではありませんか!
まとめ
MySQLI_についてSTMTオブジェクトの内容はまだいくつかありますが、それほど一般的ではありません.私たちが説明したこれらの内容からもPDOとの多くの違いがわかります.もちろん、全体の大きな方向は基本的に一致しているので、私たちは勉強しても大きな困難はありません.理解を身につけてからもっと多くのことを操作しなければなりません.基本的な仕事は決して荒廃してはいけません.
テストコード:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/8.PHPのMySQLi拡張学習(五)MySQLI_STMTオブジェクト操作php
参照ドキュメント:
https://www.php.net/manual/zh/book.mysqli.php
各メディアプラットフォームで検索可能【ハードコアプロジェクトマネージャ】