乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      PHP中的MySQLi擴(kuò)展學(xué)習(xí)(三)mysqli的基本操作

       硬核項(xiàng)目經(jīng)理 2021-05-31

      PHP中的MySQLi擴(kuò)展學(xué)習(xí)(三)mysqli的基本操作

      我們繼續(xù) MySQLi 擴(kuò)展的學(xué)習(xí),上篇文章中提到過,MySQLi 的擴(kuò)展相對(duì)于 PDO 來說功能更加的豐富,所以我們依然還會(huì)在學(xué)習(xí)過程中穿插各種 MySQLi 中好玩的方法函數(shù)。不過,今天的主角是 MySQLi 中如何執(zhí)行 SQL 語句以及多條 SQL 語句的執(zhí)行。

      連接與選擇數(shù)據(jù)庫

      首先是一個(gè)小內(nèi)容的學(xué)習(xí)分享,依然還是連接數(shù)據(jù)庫,不過這次我們用另外一種方式來進(jìn)行連接。

      $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)

      首先,我們實(shí)例化了一個(gè) mysqli 對(duì)象。在實(shí)例化過程中,我們并沒有給 mysqli 的構(gòu)造函數(shù)傳遞任何的參數(shù),而是使用 real_connect() 方法來傳遞數(shù)據(jù)庫服務(wù)器信息并建立連接。

      相信不少朋友從代碼中就可以看出,我們使用 real_connect() 可以在一個(gè) mysqli 實(shí)例下來切換不同的數(shù)據(jù)庫連接。通過打印 mysqli 對(duì)象的內(nèi)容就可以看出,兩個(gè)連接的線程ID不同,也就是說,它們是不同的兩個(gè)連接,但是使用的都是最上面所初始化的那個(gè) mysqli 對(duì)象。

      連接可以切換了,那么我們要連接的數(shù)據(jù)庫呢?當(dāng)然也可以方便地切換。

      $mysqli->select_db('mysql');

      就是這樣一個(gè)簡單的 select_db() 方法,就可以幫助我們?cè)诖a執(zhí)行過程中動(dòng)態(tài)地修改所連接的數(shù)據(jù)庫。

      執(zhí)行 SQL 語句

      對(duì)于 PDO 來說,如果是查詢語句,我們需要使用 query() 方法,如果是增、刪、改之類的其它語句,我們要使用 exec() ,通過這兩個(gè)方法分別執(zhí)行不同的 SQL 語句。但是在 MySQLi 中,我們統(tǒng)一只使用 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
      // )
      // ……

      對(duì)于增、刪、改之類的語句,query() 方法只會(huì)返回一個(gè)布爾值,也就是語句是否執(zhí)行成功。記住,它返回的不是受影響的行數(shù),這一點(diǎn)是需要注意的。我們?nèi)绻枰@取受影響的行數(shù)需要使用 MySQLi 的屬性 affected_rows 。對(duì)于插入語句來說,獲取最新插入的數(shù)據(jù)ID使用的是 insert_id 屬性。

      如果執(zhí)行的是 SELECT 語句,那么 query() 返回的就是一個(gè) mysqli_result 對(duì)象,它代表從一個(gè)數(shù)據(jù)庫查詢中獲取的結(jié)果集。關(guān)于這個(gè)對(duì)象的內(nèi)容我們將在后面的文章中進(jìn)行詳細(xì)的說明。

      執(zhí)行多條 SQL 語句

      執(zhí)行多條 SQL 語句的能力對(duì)于 PDO 來說是無法實(shí)現(xiàn)的,不過據(jù)說 PDO 是支持的,語句是可以正常執(zhí)行的,但是我們拿不到完整的返回結(jié)果。

      $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 語句的結(jié)果。如果使用 query() 方法,返回的雖然是 PDOStatement 對(duì)象,但是它是無法遍歷的。

      接下來我們就看看 MySQLi 是如何來執(zhí)行這個(gè)多條語句拼接在一起的 SQL 語句的。

      $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() 就是 MySQLi 提供的執(zhí)行多條 SQL 語句的方法。通過它執(zhí)行之后,返回的結(jié)果是一個(gè)布爾值,如果第一條語句就有問題的話,那么它返回的就是 FALSE 。如果是后面的語句錯(cuò)誤了,我們需要調(diào)用 next_result() 才能獲取后面語句的錯(cuò)誤信息。

      其實(shí)這也引出了我們 next_result() 這個(gè)方法的作用。它就相當(dāng)于是為執(zhí)行獲取下一個(gè)結(jié)果的操作做準(zhǔn)備,也可以看作是將游標(biāo)移動(dòng)到了下一條 SQL 語句上。而 more_results() 方法就是判斷是否還有更多的語句沒有執(zhí)行。

      use_result

      在上面的測試代碼中,獲得每一條語句的執(zhí)行結(jié)果使用的是 use_result() 這個(gè)方法。它的作用是啟動(dòng)結(jié)果集的檢索。也就是說,在 mutli_query() 的時(shí)候,這些語句并沒有馬上執(zhí)行,而是在調(diào)用 use_result() 時(shí),才會(huì)執(zhí)行當(dāng)前的這條語句。我們注意到 INSERT 、 UPDATE 語句返回的結(jié)果都是 FALSE 。而且 SELECT 語句中的 num_rows 也是 0 。這就是它的特點(diǎn),它也并沒有直接將結(jié)果集的信息保存在程序的內(nèi)存中。所以,use_result() 方法最大的好處就是占用內(nèi)存小,適合大量查詢的遍歷,缺點(diǎn)則是每次都要去數(shù)據(jù)庫查詢,速度慢。

      store_result

      除了 use_result() 之外,還有一個(gè) store_result() 方法可以幫助我們獲得查詢的結(jié)果集。它和 use_result() 方法是相反的,也就是說,它是直接執(zhí)行就將結(jié)果集保存在內(nèi)存中了。

      $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"
      // }

      不僅查詢結(jié)果中的 num_rows 有數(shù)據(jù)了,最后一條 SELECT now(); 語句也成功返回了。它和我們?nèi)粘J褂?query() 的結(jié)果是類似的。

      另外需要注意的一點(diǎn)是,大家可以看一下我們執(zhí)行這兩條獲取結(jié)果方式的循環(huán)條件是如何寫得。more_results() 和 next_result() 針對(duì)這兩種結(jié)果集的獲取方式也是不同的,大家可以自己測一下。

      總結(jié)

      光說不練假把式,雖說多語句執(zhí)行看似很美好,但即使在這簡單的測試代碼中,也會(huì)出現(xiàn)各種問題,大家一定要自己多嘗試一下。在日常的開發(fā)過程中,最好還是一條一條的語句來執(zhí)行,避免出現(xiàn)各種無法查明的問題而影響我們正常的業(yè)務(wù)執(zhí)行。至于到底要不要使用這個(gè)能力,還是大家仁者見仁智者見智了。

      測試代碼:

      https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/6.PHP中的MySQLi擴(kuò)展學(xué)習(xí)(三)mysqli的基本操作.php

      參考文檔:

      https://www./manual/zh/book.mysqli.php

        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多