站長(zhǎng)資訊網(wǎng)
        最全最豐富的資訊網(wǎng)站

        三分鐘帶你了解PHP中的查詢(xún)結(jié)構(gòu)集

        本篇文章給大家介紹一下PHPPHP中的查詢(xún)結(jié)構(gòu)集。有一定的參考價(jià)值,有需要的朋友可以參考一下,希望對(duì)大家有所幫助。

        三分鐘帶你了解PHP中的查詢(xún)結(jié)構(gòu)集

        PHP中的PDO操作學(xué)習(xí)(四)查詢(xún)結(jié)構(gòu)集

        關(guān)于 PDO 的最后一篇文章,我們就以查詢(xún)結(jié)果集的操作為結(jié)束。在數(shù)據(jù)庫(kù)的操作中,查詢(xún)往往占的比例非常高。在日常的開(kāi)發(fā)中,大部分的業(yè)務(wù)都是讀多寫(xiě)少型的業(yè)務(wù),所以掌握好查詢(xún)相關(guān)的操作是我們學(xué)習(xí)的重要內(nèi)容。和 mysqli 一樣,PDO 對(duì)于查詢(xún)的支持也是非常方便快捷的,通過(guò)幾個(gè)函數(shù)就可以非常方便高效地操作各種查詢(xún)語(yǔ)句。

        在使用預(yù)處理語(yǔ)句的情況下,我們使用 execute() 執(zhí)行之后,查詢(xún)的結(jié)果集就會(huì)保存在 PDOStatement 對(duì)象中。對(duì)于數(shù)據(jù)的操作就轉(zhuǎn)移到了 PHP 的對(duì)象中,所以我們需要 PDOStatement 的一些方法來(lái)獲得結(jié)果集的內(nèi)容。

        fetch() 方法

        通過(guò) fetch() 方法,獲得的是查詢(xún)結(jié)果集的下一行。

        $stmt = $pdo->prepare("select * from zyblog_test_user"); $stmt->execute();  $row = $stmt->fetch(); print_r($row); // Array // ( //     [id] => 1 //     [0] => 1 //     [username] => aaa //     [1] => aaa //     [password] => aaa //     [2] => aaa //     [salt] => aaa //     [3] => aaa // )

        從返回的結(jié)果來(lái)看,我們沒(méi)有給 PDO 對(duì)象指定 PDO::ATTR_DEFAULT_FETCH_MODE 屬性,所以它是返回的默認(rèn)的 PDO::FETCH_BOTH 格式,也就是字段名和下標(biāo)同時(shí)存在的。其實(shí)這個(gè)方法可以直接指定我們需要的 FETCH_STYLE 。

        結(jié)果集類(lèi)型指定

        $row = $stmt->fetch(PDO::FETCH_ASSOC); print_r($row); // Array // ( //     [id] => 2 //     [username] => bbb //     [password] => bbb //     [salt] => 123 // )  $row = $stmt->fetch(PDO::FETCH_LAZY); print_r($row); // PDORow Object // ( //     [queryString] => select * from zyblog_test_user //     [id] => 3 //     [username] => ccc //     [password] => bbb //     [salt] => c3 // )  $row = $stmt->fetch(PDO::FETCH_OBJ); print_r($row); // stdClass Object // ( //     [id] => 4 //     [username] => ccc //     [password] => bbb //     [salt] => c3 // )

        和指定 PDO 對(duì)象的 PDO::ATTR_DEFAULT_FETCH_MODE 一樣。使用 fetch() 方法時(shí)直接將需要的返回結(jié)果類(lèi)型參數(shù)指定到方法的第一個(gè)參數(shù),就實(shí)現(xiàn)了 FETCH_STYLE 的指定。具體支持的格式和之前講過(guò)的 PDO 對(duì)象的 PDO::ATTR_DEFAULT_FETCH_MODE 屬性是完全一樣的,大家可以自行查閱。

        獲取全部數(shù)據(jù)

        從代碼和定義中可以看出,fetch() 方法是獲取當(dāng)前數(shù)據(jù)集的下一行數(shù)據(jù),就像數(shù)據(jù)庫(kù)的游標(biāo)操作一樣。所以,我們可以通過(guò)循環(huán) fetch() 來(lái)對(duì)結(jié)果集進(jìn)行遍歷,從而獲得所有的結(jié)果集數(shù)據(jù)。

         while($row = $stmt->fetch()){     print_r($row); } // Array // ( //     [id] => 2 //     [0] => 2 //     [username] => bbb //     [1] => bbb //     [password] => bbb //     [2] => bbb //     [salt] => 123 //     [3] => 123 // ) // ……

        MySQL 不支持游標(biāo)

        上文中提到了游標(biāo)操作,PDO 擴(kuò)展是支持游標(biāo)的,但是需要注意的是,MySQL 擴(kuò)展并不支持這個(gè)操作。所以我們使用游標(biāo)相關(guān)的屬性對(duì)于 MySQL 庫(kù)是沒(méi)有效果的。

        $stmt = $pdo->prepare("select * from zyblog_test_user", [PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL]); $stmt->execute();  $row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT); print_r($row); // Array // ( //     [id] => 1 //     [username] => aaa //     [password] => aaa //     [salt] => aaa // )  $stmt = $pdo->prepare("select * from zyblog_test_user", [PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL]); $stmt->execute();  $row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_LAST); print_r($row); // Array // ( //     [id] => 1 //     [username] => aaa //     [password] => aaa //     [salt] => aaa // )

        如果是支持游標(biāo)操作的數(shù)據(jù)庫(kù)及擴(kuò)展的話,上面代碼中的 fetch() 的第二個(gè)參數(shù)指定后,獲取的結(jié)果是會(huì)不同的。PDO::FETCH_ORI_NEXT 是獲取游標(biāo)的下一條數(shù)據(jù),而 PDO::FETCH_ORI_LAST 是獲取游標(biāo)的最后一條數(shù)據(jù)。但是在我們對(duì) MySQL 的測(cè)試中,它們并沒(méi)有任何效果,依然是獲取結(jié)果集的下一條數(shù)據(jù)。

        fetchAll() 方法

        通過(guò) fetch() 方法,我們可以獲得結(jié)果集中的全部數(shù)據(jù),不過(guò)還是需要一個(gè)循環(huán)才能進(jìn)行遍歷,多少還是有點(diǎn)麻煩。其實(shí),PDO 早就為我們準(zhǔn)備好了另一個(gè)方法,fetchAll() 就是返回一個(gè)包含結(jié)果集中所有行的數(shù)組。

        $stmt = $pdo->prepare("select * from zyblog_test_user limit 2"); $stmt->execute();  $list = $stmt->fetchAll(); print_r($list); // Array // ( //     [0] => Array //         ( //             [id] => 1 //             [0] => 1 //             [username] => aaa //             [1] => aaa //             [password] => aaa //             [2] => aaa //             [salt] => aaa //             [3] => aaa //         )  //     [1] => Array //         ( //             [id] => 2 //             [0] => 2 //             [username] => bbb //             [1] => bbb //             [password] => bbb //             [2] => bbb //             [salt] => 123 //             [3] => 123 //         )  // )

        fetchAll() 就是在內(nèi)部使用了 fetch() 幫我們遍歷了一次結(jié)果集并且賦值到了一個(gè)數(shù)組中。所以我們?nèi)绻诓恢匦?execute() 情況下再次調(diào)用 fetchAll() 的話,獲取的就是空的數(shù)據(jù)。因?yàn)橛螛?biāo)已經(jīng)到底了。

        $list = $stmt->fetchAll(); print_r($list); // Array // ( // )

        它同樣支持指定 FETCH_STYLE ,也和 fetch() 方法一樣,直接將需要的類(lèi)型常量賦值給第一個(gè)參數(shù)就可以了。

        // PDO::FETCH_ASSOC $stmt = $pdo->prepare("select * from zyblog_test_user limit 2"); $stmt->execute();  $list = $stmt->fetchAll(PDO::FETCH_ASSOC); print_r($list); // Array // ( //     [0] => Array //         ( //             [id] => 1 //             [username] => aaa //             [password] => aaa //             [salt] => aaa //         )  //     [1] => Array //         ( //             [id] => 2 //             [username] => bbb //             [password] => bbb //             [salt] => 123 //         )  // )  // PDO::FETCH_COLUMN $stmt = $pdo->prepare("select * from zyblog_test_user limit 2"); $stmt->execute();  $list = $stmt->fetchAll(PDO::FETCH_COLUMN, 1); print_r($list); // Array // ( //     [0] => aaa //     [1] => bbb // )  // PDO::FETCH_CLASS class User{     function __construct($a){         echo $a, PHP_EOL;     } } $stmt = $pdo->prepare("select * from zyblog_test_user limit 2"); $stmt->execute(); $list = $stmt->fetchAll(PDO::FETCH_CLASS, 'User', ['FetchAll User']); print_r($list); // FetchAll User // FetchAll User // Array // ( //     [0] => User Object //         ( //             [id] => 1 //             [username] => aaa //             [password] => aaa //             [salt] => aaa //         )  //     [1] => User Object //         ( //             [id] => 2 //             [username] => bbb //             [password] => bbb //             [salt] => 123 //         )  // )

        是不是非常熟悉了,這里就不多講了,關(guān)于 FETCH_STYLE 的類(lèi)型指定已經(jīng)說(shuō)過(guò)很多遍了,它的用法和 fetch() 以及 PDO 對(duì)象中的 query() 方法都是差不多的。不過(guò)它還支持一種以回調(diào)方式調(diào)用一個(gè)方法的形式來(lái)獲得數(shù)據(jù)集。

        function getValue(){     print_r(func_get_args()); } // Array // ( //     [0] => 1 //     [1] => aaa //     [2] => aaa //     [3] => aaa // ) // Array // ( //     [0] => 2 //     [1] => bbb //     [2] => bbb //     [3] => 123 // ) $stmt = $pdo->prepare("select * from zyblog_test_user limit 2"); $stmt->execute(); $list = $stmt->fetchAll(PDO::FETCH_FUNC, 'getValue'); print_r($list); // Array // ( //     [0] =>  //     [1] =>  // )

        在這段代碼中,我們使用的是 PDO::FETCH_FUNC ,第二個(gè)參數(shù)是一個(gè)方法名稱(chēng)。這樣每一條結(jié)構(gòu)集都會(huì)在遍歷的時(shí)候作為方法的參數(shù)去調(diào)用指定的這個(gè)方法,我們通過(guò) func_get_args() 就可以獲取到這些參數(shù)內(nèi)容。在這段代碼中,結(jié)果集并不會(huì)通過(guò) fetchAll() 方法的返回值賦值給 $list 變量了。因?yàn)閿?shù)據(jù)都已經(jīng)傳遞給了指定的 getValue() 方法了。

        fetchColumn() 方法

        在上面的測(cè)試代碼中,我們使用過(guò) PDO::FETCH_COLUMN 來(lái)獲取結(jié)果集的某一列數(shù)據(jù)。這樣寫(xiě)沒(méi)什么問(wèn)題,但是還有更方便的方式,也就是 PDOStatment 直接為我們提供的一個(gè) fetchColumn() 方法。它就相當(dāng)于是默認(rèn)的在方法內(nèi)部指定了 PDO::FETCH_COLUMN ,并且只需要一個(gè)參數(shù)就是列的下標(biāo)。

        需要注意的是,它的返回是下一行的指定列值,也就是說(shuō),它在底層是調(diào)用的 fetch() 方法。如果要獲取結(jié)果集中所有指定列的內(nèi)容,我們還需要通過(guò)和 fetch() 的遍歷方式一樣的方法來(lái)遍歷結(jié)果集。

        // fetchColumn $stmt = $pdo->prepare("select * from zyblog_test_user"); $stmt->execute(); $column = $stmt->fetchColumn(2); echo $column, PHP_EOL; // aaa  $column = $stmt->fetchColumn(3); echo $column, PHP_EOL; // 123

        fetchObject() 方法

        fetchObject() 就不用多解釋了,它和 fetchColumn() 是類(lèi)似的,只是返回的是下一行數(shù)據(jù)的對(duì)象格式。同樣的,它也是可以傳遞構(gòu)造參數(shù)的,這點(diǎn)和 PDO 對(duì)象的 query() 中指定的 PDO::FETCH_CLASS 格式的使用是一樣的。我們?cè)诘谝黄恼轮芯陀兄v解。

        // fetchObject $stmt = $pdo->prepare("select * from zyblog_test_user"); $stmt->execute(); $user = $stmt->fetchObject('User', ['FetchObject User']); print_r($user); // FetchObject User // User Object // ( //     [id] => 1 //     [username] => aaa //     [password] => aaa //     [salt] => aaa // )

        rowCount() 返回查詢(xún)結(jié)果數(shù)量

        要獲得查詢(xún)的結(jié)果集行數(shù)就需要我們的 rowCount() 方法了。數(shù)據(jù)庫(kù)中不管是查詢(xún)還是增、刪、改操作,都會(huì)返回語(yǔ)句執(zhí)行結(jié)果,也就是受影響的行數(shù)。這些信息都是通過(guò) rowCount() 這個(gè)方法獲得的。

        查詢(xún)語(yǔ)句返回行數(shù)

        需要注意的是,在查詢(xún)語(yǔ)句中,有些數(shù)據(jù)是可能返回此語(yǔ)句的行數(shù)的。但這種方式不能保證對(duì)所有數(shù)據(jù)有效,且對(duì)可移植的應(yīng)用更不要依賴(lài)這種方式。我們?nèi)绻枰喇?dāng)前查詢(xún)結(jié)果的數(shù)量,還是通過(guò)遍歷 fetch() 或者通過(guò) count(fetchAll()) 來(lái)根據(jù)真實(shí)查詢(xún)到的結(jié)果集數(shù)量確定這一次查詢(xún)的真實(shí)行數(shù)。

        其實(shí)它就像是 PDO 對(duì)象的 exec() 方法所返回的數(shù)據(jù)。在不使用預(yù)處理語(yǔ)句的情況下,直接使用 PDO 的 exec() 方法執(zhí)行 SQL 語(yǔ)句后,返回的也是語(yǔ)句執(zhí)行后受影響的行數(shù)。

        $stmt = $pdo->prepare("select * from zyblog_test_user"); $stmt->execute(); $rowCount = $stmt->rowCount(); echo $rowCount, PHP_EOL; // 41

        增、刪、改語(yǔ)句返回受影響的行數(shù)

        $stmt = $pdo->prepare("insert into zyblog_test_user(username, password, salt) values(?, ?, ?)"); $stmt->execute(['kkk','666','k6']); $rowCount = $stmt->rowCount(); echo $rowCount, PHP_EOL; // 1 $id = $pdo->lastInsertId(); echo $rowCount, PHP_EOL; // 1  $stmt = $pdo->prepare("update zyblog_test_user set username=? where username = ?"); $stmt->execute(['ccc','cccc']); $rowCount = $stmt->rowCount(); echo $rowCount, PHP_EOL; // 25  $stmt = $pdo->prepare("update zyblog_test_user set username=? where username = ?"); $stmt->execute(['ccc','cccc']); $rowCount = $stmt->rowCount(); echo $rowCount, PHP_EOL; // 0  $stmt = $pdo->prepare("delete from zyblog_test_user where username = ?"); $stmt->execute(['ddd']); $rowCount = $stmt->rowCount(); echo $rowCount, PHP_EOL; // 11  $stmt = $pdo->prepare("delete from zyblog_test_user where username = ?"); $stmt->execute(['ddd']); $rowCount = $stmt->rowCount(); echo $rowCount, PHP_EOL; // 0

        更新和刪除操作在數(shù)據(jù)不存在、沒(méi)有更新、沒(méi)有刪除的情況下都返回的是 0 。這一點(diǎn)我們也在 PDO 相關(guān)的第一篇文章中就說(shuō)過(guò)了,對(duì)于業(yè)務(wù)來(lái)說(shuō),這種更新或刪除到底算是成功還是失敗呢?還是大家根據(jù)自己的實(shí)際業(yè)務(wù)情況來(lái)確定吧!

        總結(jié)

        關(guān)于 PDO 和 PDOStatement 相關(guān)的內(nèi)容就學(xué)習(xí)到這里了。我們完整地梳理了一遍它們兩個(gè)所有的方法,也都進(jìn)行了相關(guān)的測(cè)試。大家在日常使用中可能接觸到的并不多,框架都已經(jīng)為我們封裝好了。不過(guò)對(duì)于學(xué)習(xí)來(lái)說(shuō),平常的小測(cè)試、小調(diào)試完全可以自己手寫(xiě)來(lái)加深記憶和理解。在深入理解了這些擴(kuò)展類(lèi)的使用方法后,反過(guò)來(lái)又能幫助我們更加的清楚框架是如何去封裝它們的。總之,學(xué)習(xí)就是不斷的從高層到底層,再?gòu)牡讓臃祷馗邔樱h(huán)往復(fù),才能更加的得心應(yīng)手。

        測(cè)試代碼:

        https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/PHP%E4%B8%AD%E7%9A%84PDO%E6%93%8D%E4%BD%9C%E5%AD%A6%E4%B9%A0%EF%BC%88%E5%9B%9B%EF%BC%89%E6%9F%A5%E8%AF%A2%E7%BB%93%E6%9E%84%E9%9B%86.php

        推薦學(xué)習(xí):php視頻教程

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)
        主站蜘蛛池模板: 色欲精品国产一区二区三区AV| 久久99久久99小草精品免视看| 99精品热这里只有精品| 精品亚洲欧美中文字幕在线看 | 久久精品国产半推半就| 亚洲精品乱码久久久久久蜜桃不卡 | 久久99热精品| 国产美女久久精品香蕉69| 久久精品中文字幕一区| 91精品日韩人妻无码久久不卡| 91老司机深夜福利精品视频在线观看 | 91国内揄拍国内精品情侣对白| 精品久久久久久无码专区| 中文字幕在线亚洲精品| 久久精品国产色蜜蜜麻豆| 99热亚洲精品6码| 久久精品男人影院| 国产精品你懂得| 国产精品白丝AV网站| 久久国产精品99国产精| 无码国产精品一区二区免费3p| 亚洲欧美国产∧v精品综合网 | 国产成人精品无码一区二区| 亚洲Av永久无码精品三区在线| 亚洲av午夜精品一区二区三区 | 99久re热视频这里只有精品6| 久久精品无码一区二区三区| 精品国产一区二区三区免费| 99国产精品一区二区| 国产福利91精品一区二区三区| 国产精品久久久久久久久免费 | 日韩国产成人精品视频| 亚洲av永久无码精品表情包 | 中文字幕精品视频在线| 亚洲国产精品无码久久久蜜芽 | 国产成人精品视频在放| 亚洲日韩精品射精日| 亚洲欧美激情精品一区二区| 亚洲处破女AV日韩精品| 亚洲线精品一区二区三区影音先锋| 亚洲精品午夜国产VA久久成人|