溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

PHP中的查詢結(jié)構(gòu)集有什么用

發(fā)布時間:2021-06-18 17:39:02 來源:億速云 閱讀:144 作者:chen 欄目:編程語言

這篇文章主要講解了“PHP中的查詢結(jié)構(gòu)集有什么用”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“PHP中的查詢結(jié)構(gòu)集有什么用”吧!

PHP中的PDO操作學(xué)習(xí)查詢結(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() 方法

通過 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 。

結(jié)果集類型指定

$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 屬性是完全一樣的,大家可以自行查閱。

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

從代碼和定義中可以看出,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
// )
// ……

MySQL 不支持游標(biāo)

上文中提到了游標(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ù)。

fetchAll() 方法

通過 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() 方法了。

fetchColumn() 方法

在上面的測試代碼中,我們使用過 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() 方法

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

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

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

查詢語句返回行數(shù)

需要注意的是,在查詢語句中,有些數(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

增、刪、改語句返回受影響的行數(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ù)不存在、沒有更新、沒有刪除的情況下都返回的是 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)注!

向AI問一下細(xì)節(jié)

免責(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)容。

php
AI