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