MySQLi の拡張機能は PDO よりも機能的であるため、学習プロセス中に MySQLi にさまざまな興味深いメソッドや関数を散りばめる予定です。ただし、今日の主役は、MySQLi で SQL ステートメントを実行する方法と複数の SQL ステートメントを実行する方法です。
まず、小さな学習共有ですが、まだデータベースに接続していますが、これは接続する別の方法。
$mysqli = new mysqli(); $mysqli->real_connect("localhost", "root", "", "blog_test"); var_dump($mysqli); // ["thread_id"]=> // int(163) $mysqli->real_connect("localhost", "root2", "123", "blog_test"); var_dump($mysqli); // ["thread_id"]=> // int(164)
まず、mysqli オブジェクトをインスタンス化します。インスタンス化プロセス中に、mysqli コンストラクターにパラメーターを渡しませんでしたが、real_connect() メソッドを使用してデータベース サーバー情報を渡し、接続を確立しました。
このコードから、mysqli インスタンス内で real_connect() を使用してさまざまなデータベース接続を切り替えることができることが多くの友人にわかると思います。 mysqli オブジェクトの内容を出力すると、2 つの接続のスレッド ID が異なることがわかります。つまり、これらは 2 つの異なる接続ですが、先頭で初期化された mysqli オブジェクトを使用していることがわかります。
接続は切り替えることができますが、接続したいデータベースはどうすればよいでしょうか?もちろん切り替えも簡単に行えます。
$mysqli->select_db('mysql');
これは非常に単純な select_db() メソッドで、コードの実行中に接続されたデータベースを動的に変更するのに役立ちます。
PDO の場合、クエリ ステートメントの場合は、query() メソッドを使用する必要があります。追加、削除、変更の場合は、 etc ステートメントでは、exec() を使用して、これら 2 つのメソッドを通じてさまざまな SQL ステートメントを実行する必要があります。ただし、MySQLi では、query() メソッドのみを使用できます。
$mysqli->query("insert into zyblog_test_user(username, password, salt) values('3a', '3a', '3a')"); var_dump($mysqli->affected_rows); var_dump($mysqli->insert_id); $mysqli->query("update zyblog_test_user set password='3aa' where username='3a'"); var_dump($mysqli->affected_rows); $mysqli->query("delete from zyblog_test_user where id = 60"); var_dump($mysqli->affected_rows); $res = $mysqli->query("select * from zyblog_test_user where username='3a'"); print_r($res); // mysqli_result Object // ( // [current_field] => 0 // [field_count] => 4 // [lengths] => // [num_rows] => 3 // [type] => 0 // ) print_r($res->fetch_assoc()); // Array // ( // [id] => 61 // [username] => 3a // [password] => 3aa // [salt] => 3a // ) while ($row = $res->fetch_assoc()) { print_r($row); } // Array // ( // [id] => 62 // [username] => 3a // [password] => 3aa // [salt] => 3a // ) // Array // ( // [id] => 63 // [username] => 3a // [password] => 3aa // [salt] => 3a // ) // ……
add、delete、modify などのステートメントの場合、query() メソッドはブール値、つまりステートメントが正常に実行されたかどうかのみを返します。影響を受ける行数は返されないことに注意してください。これは重要な点です。影響を受ける行の数を取得する必要がある場合は、MySQLi 属性affected_rows を使用する必要があります。 insert ステートメントの場合、insert_id 属性を使用して、最新の挿入データ ID を取得します。
SELECT ステートメントが実行されると、query() はデータベース クエリから取得された結果セットを表す mysqli_result オブジェクトを返します。このオブジェクトの内容については、後の記事で詳しく説明します。
複数の SQL ステートメントを実行する機能は PDO では不可能ですが、PDO はそれをサポートしており、ステートメントは正常に動作すると言われています。 , しかし、完全な戻り結果を取得することはできません。
$sql = "insert into zyblog_test_user(username, password, salt) values('3bb', '3bb', '3bb');" . "update zyblog_test_user set password='3aa' where username='3a';" . "select * from zyblog_test_user where username='3b';" . "select now()"; $pdo = new PDO("mysql:dns=locahost;dbname=blog_test", 'root', '', [PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION]); $res = $pdo->exec($sql); var_dump($res); // int(1) $stmt = $pdo->query($sql); foreach ($stmt as $row) { //PHP Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error in var_dump($row); }
コードからわかるように、exec() メソッドを使用すると、INSERT ステートメントの結果が返されます。 query() メソッドを使用すると、PDOStatement オブジェクトは返されますが、それを走査することはできません。
次に、結合された複数のステートメントで構成されるこの SQL ステートメントを MySQLi がどのように実行するかを見てみましょう。
$mysqli->multi_query($sql); $i = 1; do{ echo '第' . $i . '条:', PHP_EOL; $i++; $result = $mysqli->use_result(); var_dump($result); var_dump($mysqli->affected_rows); if(is_object($result)){ var_dump($result->fetch_assoc()); } var_dump($mysqli->next_result()); echo '========', PHP_EOL; } while($mysqli->more_results() ); // 第1条: // bool(false) // int(1) // ======== // 第2条: // bool(false) // int(0) // ======== // 第3条: // object(mysqli_result)#2 (5) { // ["current_field"]=> // int(0) // ["field_count"]=> // int(4) // ["lengths"]=> // NULL // ["num_rows"]=> // int(0) // ["type"]=> // int(1) // } // int(-1) // array(4) { // ["id"]=> // string(2) "67" // ["username"]=> // string(2) "3b" // ["password"]=> // string(2) "3b" // ["salt"]=> // string(2) "3b" // } // ======== // 第4条: // bool(false) // int(0) // ========
multi_query() は、複数の SQL ステートメントを実行するために MySQLi によって提供されるメソッドです。実行後、返される結果はブール値で、最初のステートメントに問題がある場合は FALSE を返します。後続のステートメントが間違っている場合は、next_result() を呼び出して後続のステートメントのエラー情報を取得する必要があります。
実際、これは next_result() メソッドの役割にもつながります。これは、次の結果を取得する操作の準備に相当し、カーソルを次の SQL 文に移動すると見ることもできます。 more_results() メソッドは、まだ実行されていないステートメントが他にあるかどうかを判断します。
上記のテスト コードでは、use_result() メソッドを使用して各ステートメントの実行結果を取得しています。その機能は、結果セットの取得を開始することです。つまり、mutli_query() が呼び出されたときに、これらのステートメントはすぐには実行されませんが、use_result() が呼び出されたときに現在のステートメントが実行されます。 INSERT ステートメントと UPDATE ステートメントによって返される結果が FALSE であることに気付きました。また、SELECT ステートメントの num_rows も 0 です。これはその特性であり、結果セットの情報をプログラムのメモリに直接保存しません。したがって、 use_result() メソッドの最大の利点は、使用するメモリが少なく、多数のクエリの実行に適していることですが、欠点は、毎回データベースにアクセスしてクエリを実行する必要があり、時間がかかることです。
use_result() に加えて、クエリの結果セットの取得に役立つ store_result() メソッドもあります。これは use_result() メソッドの逆です。つまり、直接実行して結果セットをメモリに保存します。
$mysqli = new mysqli("localhost", "root", "", "blog_test"); $mysqli->multi_query($sql); $i = 1; do{ echo '第' . $i . '条:', PHP_EOL; $i++; $result = $mysqli->store_result(); var_dump($result); var_dump($mysqli->affected_rows); if(is_object($result)){ var_dump($result->fetch_assoc()); } var_dump($mysqli->next_result()); echo '========', PHP_EOL; } while($mysqli->more_results() ); // 第1条: // bool(false) // int(1) // ======== // 第2条: // bool(false) // int(0) // ======== // 第3条: // object(mysqli_result)#1 (5) { // ["current_field"]=> // int(0) // ["field_count"]=> // int(4) // ["lengths"]=> // NULL // ["num_rows"]=> // int(7) // ["type"]=> // int(0) // } // int(7) // array(4) { // ["id"]=> // string(2) "67" // ["username"]=> // string(2) "3b" // ["password"]=> // string(2) "3b" // ["salt"]=> // string(2) "3b" // } // ======== // 第4条: // object(mysqli_result)#3 (5) { // ["current_field"]=> // int(0) // ["field_count"]=> // int(1) // ["lengths"]=> // NULL // ["num_rows"]=> // int(1) // ["type"]=> // int(0) // } // int(1) // array(1) { // ["now()"]=> // string(19) "2020-09-14 10:31:37" // }
クエリ結果の num_rows にデータがあるだけでなく、最後の SELECT now(); ステートメントも正常に返されます。これは、query() を毎日使用した結果と似ています。
もう 1 つ注意すべき点は、結果を取得するこれら 2 つの方法を実行するためのループ条件の記述方法を確認できることです。 more_results() と next_result() は、これら 2 つの結果セットを取得する異なる方法を持っています。
光说不练假把式,虽说多语句执行看似很美好,但即使在这简单的测试代码中,也会出现各种问题,大家一定要自己多尝试一下。在日常的开发过程中,最好还是一条一条的语句来执行,避免出现各种无法查明的问题而影响我们正常的业务执行。至于到底要不要使用这个能力,还是大家仁者见仁智者见智了。
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/6.PHP中的MySQLi扩展学习(三)mysqli的基本操作.php
推荐学习:php视频教程
以上がPHP での mysqli の基本的な操作は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。