您好,登錄后才能下訂單哦!
這篇文章主要講解了“PHP中的查詢結(jié)構(gòu)集有什么用”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“PHP中的查詢結(jié)構(gòu)集有什么用”吧!
關(guān)于 PDO 的最后一篇文章,我們就以查詢結(jié)果集的操作為結(jié)束。在數(shù)據(jù)庫的操作中,查詢往往占的比例非常高。在日常的開發(fā)中,大部分的業(yè)務(wù)都是讀多寫少型的業(yè)務(wù),所以掌握好查詢相關(guān)的操作是我們學(xué)習(xí)的重要內(nèi)容。和 mysqli 一樣,PDO 對于查詢的支持也是非常方便快捷的,通過幾個函數(shù)就可以非常方便高效地操作各種查詢語句。
在使用預(yù)處理語句的情況下,我們使用 execute() 執(zhí)行之后,查詢的結(jié)果集就會保存在 PDOStatement 對象中。對于數(shù)據(jù)的操作就轉(zhuǎn)移到了 PHP 的對象中,所以我們需要 PDOStatement 的一些方法來獲得結(jié)果集的內(nèi)容。
通過 fetch() 方法,獲得的是查詢結(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é)果來看,我們沒有給 PDO 對象指定 PDO::ATTR_DEFAULT_FETCH_MODE 屬性,所以它是返回的默認(rèn)的 PDO::FETCH_BOTH 格式,也就是字段名和下標(biāo)同時存在的。其實(shí)這個方法可以直接指定我們需要的 FETCH_STYLE 。
$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 對象的 PDO::ATTR_DEFAULT_FETCH_MODE 一樣。使用 fetch() 方法時直接將需要的返回結(jié)果類型參數(shù)指定到方法的第一個參數(shù),就實(shí)現(xiàn)了 FETCH_STYLE 的指定。具體支持的格式和之前講過的 PDO 對象的 PDO::ATTR_DEFAULT_FETCH_MODE 屬性是完全一樣的,大家可以自行查閱。
從代碼和定義中可以看出,fetch() 方法是獲取當(dāng)前數(shù)據(jù)集的下一行數(shù)據(jù),就像數(shù)據(jù)庫的游標(biāo)操作一樣。所以,我們可以通過循環(huán) fetch() 來對結(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 // ) // ……
上文中提到了游標(biāo)操作,PDO 擴(kuò)展是支持游標(biāo)的,但是需要注意的是,MySQL 擴(kuò)展并不支持這個操作。所以我們使用游標(biāo)相關(guān)的屬性對于 MySQL 庫是沒有效果的。
$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ù)庫及擴(kuò)展的話,上面代碼中的 fetch() 的第二個參數(shù)指定后,獲取的結(jié)果是會不同的。PDO::FETCH_ORI_NEXT 是獲取游標(biāo)的下一條數(shù)據(jù),而 PDO::FETCH_ORI_LAST 是獲取游標(biāo)的最后一條數(shù)據(jù)。但是在我們對 MySQL 的測試中,它們并沒有任何效果,依然是獲取結(jié)果集的下一條數(shù)據(jù)。
通過 fetch() 方法,我們可以獲得結(jié)果集中的全部數(shù)據(jù),不過還是需要一個循環(huán)才能進(jìn)行遍歷,多少還是有點(diǎn)麻煩。其實(shí),PDO 早就為我們準(zhǔn)備好了另一個方法,fetchAll() 就是返回一個包含結(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é)果集并且賦值到了一個數(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() 方法一樣,直接將需要的類型常量賦值給第一個參數(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 的類型指定已經(jīng)說過很多遍了,它的用法和 fetch() 以及 PDO 對象中的 query() 方法都是差不多的。不過它還支持一種以回調(diào)方式調(diào)用一個方法的形式來獲得數(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 ,第二個參數(shù)是一個方法名稱。這樣每一條結(jié)構(gòu)集都會在遍歷的時候作為方法的參數(shù)去調(diào)用指定的這個方法,我們通過 func_get_args() 就可以獲取到這些參數(shù)內(nèi)容。在這段代碼中,結(jié)果集并不會通過 fetchAll() 方法的返回值賦值給 $list 變量了。因?yàn)閿?shù)據(jù)都已經(jīng)傳遞給了指定的 getValue() 方法了。
在上面的測試代碼中,我們使用過 PDO::FETCH_COLUMN 來獲取結(jié)果集的某一列數(shù)據(jù)。這樣寫沒什么問題,但是還有更方便的方式,也就是 PDOStatment 直接為我們提供的一個 fetchColumn() 方法。它就相當(dāng)于是默認(rèn)的在方法內(nèi)部指定了 PDO::FETCH_COLUMN ,并且只需要一個參數(shù)就是列的下標(biāo)。
需要注意的是,它的返回是下一行的指定列值,也就是說,它在底層是調(diào)用的 fetch() 方法。如果要獲取結(jié)果集中所有指定列的內(nèi)容,我們還需要通過和 fetch() 的遍歷方式一樣的方法來遍歷結(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() 就不用多解釋了,它和 fetchColumn() 是類似的,只是返回的是下一行數(shù)據(jù)的對象格式。同樣的,它也是可以傳遞構(gòu)造參數(shù)的,這點(diǎn)和 PDO 對象的 query() 中指定的 PDO::FETCH_CLASS 格式的使用是一樣的。我們在第一篇文章中就有講解。
// 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 // )
要獲得查詢的結(jié)果集行數(shù)就需要我們的 rowCount() 方法了。數(shù)據(jù)庫中不管是查詢還是增、刪、改操作,都會返回語句執(zhí)行結(jié)果,也就是受影響的行數(shù)。這些信息都是通過 rowCount() 這個方法獲得的。
需要注意的是,在查詢語句中,有些數(shù)據(jù)是可能返回此語句的行數(shù)的。但這種方式不能保證對所有數(shù)據(jù)有效,且對可移植的應(yīng)用更不要依賴這種方式。我們?nèi)绻枰喇?dāng)前查詢結(jié)果的數(shù)量,還是通過遍歷 fetch() 或者通過 count(fetchAll()) 來根據(jù)真實(shí)查詢到的結(jié)果集數(shù)量確定這一次查詢的真實(shí)行數(shù)。
其實(shí)它就像是 PDO 對象的 exec() 方法所返回的數(shù)據(jù)。在不使用預(yù)處理語句的情況下,直接使用 PDO 的 exec() 方法執(zhí)行 SQL 語句后,返回的也是語句執(zhí)行后受影響的行數(shù)。
$stmt = $pdo->prepare("select * from zyblog_test_user"); $stmt->execute(); $rowCount = $stmt->rowCount(); echo $rowCount, PHP_EOL; // 41
$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ù)不存在、沒有更新、沒有刪除的情況下都返回的是 0 。這一點(diǎn)我們也在 PDO 相關(guān)的第一篇文章中就說過了,對于業(yè)務(wù)來說,這種更新或刪除到底算是成功還是失敗呢?還是大家根據(jù)自己的實(shí)際業(yè)務(wù)情況來確定吧!
感謝各位的閱讀,以上就是“PHP中的查詢結(jié)構(gòu)集有什么用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對PHP中的查詢結(jié)構(gòu)集有什么用這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。