Jadual Kandungan
PHP中的PDO操作学习(四)查询结构集" >PHP中的PDO操作学习(四)查询结构集
fetch() 方法" >fetch() 方法
结果集类型指定
获取全部数据
MySQL 不支持游标
fetchAll() 方法" >fetchAll() 方法
fetchColumn() 方法" >fetchColumn() 方法
fetchObject() 方法" >fetchObject() 方法
rowCount() 返回查询结果数量" >rowCount() 返回查询结果数量
查询语句返回行数
增、删、改语句返回受影响的行数
总结" >总结
Rumah pembangunan bahagian belakang masalah PHP 三分钟带你了解PHP中的查询结构集

三分钟带你了解PHP中的查询结构集

Jun 18, 2021 pm 05:04 PM
php

本篇文章给大家介绍一下PHPPHP中的查询结构集。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

三分钟带你了解PHP中的查询结构集

PHP中的PDO操作学习(四)查询结构集

关于 PDO 的最后一篇文章,我们就以查询结果集的操作为结束。在数据库的操作中,查询往往占的比例非常高。在日常的开发中,大部分的业务都是读多写少型的业务,所以掌握好查询相关的操作是我们学习的重要内容。和 mysqli 一样,PDO 对于查询的支持也是非常方便快捷的,通过几个函数就可以非常方便高效地操作各种查询语句。

在使用预处理语句的情况下,我们使用 execute() 执行之后,查询的结果集就会保存在 PDOStatement 对象中。对于数据的操作就转移到了 PHP 的对象中,所以我们需要 PDOStatement 的一些方法来获得结果集的内容。

fetch() 方法

通过 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
// )
Salin selepas log masuk

从返回的结果来看,我们没有给 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
// )
Salin selepas log masuk

和指定 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
// )
// ……
Salin selepas log masuk

MySQL 不支持游标

上文中提到了游标操作,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
// )
Salin selepas log masuk

如果是支持游标操作的数据库及扩展的话,上面代码中的 fetch() 的第二个参数指定后,获取的结果是会不同的。PDO::FETCH_ORI_NEXT 是获取游标的下一条数据,而 PDO::FETCH_ORI_LAST 是获取游标的最后一条数据。但是在我们对 MySQL 的测试中,它们并没有任何效果,依然是获取结果集的下一条数据。

fetchAll() 方法

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

// )
Salin selepas log masuk

fetchAll() 就是在内部使用了 fetch() 帮我们遍历了一次结果集并且赋值到了一个数组中。所以我们如果在不重新 execute() 情况下再次调用 fetchAll() 的话,获取的就是空的数据。因为游标已经到底了。

$list = $stmt->fetchAll();
print_r($list);
// Array
// (
// )
Salin selepas log masuk

它同样支持指定 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
//         )

// )
Salin selepas log masuk

是不是非常熟悉了,这里就不多讲了,关于 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] => 
// )
Salin selepas log masuk

在这段代码中,我们使用的是 PDO::FETCH_FUNC ,第二个参数是一个方法名称。这样每一条结构集都会在遍历的时候作为方法的参数去调用指定的这个方法,我们通过 func_get_args() 就可以获取到这些参数内容。在这段代码中,结果集并不会通过 fetchAll() 方法的返回值赋值给 $list 变量了。因为数据都已经传递给了指定的 getValue() 方法了。

fetchColumn() 方法

在上面的测试代码中,我们使用过 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
Salin selepas log masuk

fetchObject() 方法

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
// )
Salin selepas log masuk

rowCount() 返回查询结果数量

要获得查询的结果集行数就需要我们的 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
Salin selepas log masuk

增、删、改语句返回受影响的行数

$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
Salin selepas log masuk

更新和删除操作在数据不存在、没有更新、没有删除的情况下都返回的是 0 。这一点我们也在 PDO 相关的第一篇文章中就说过了,对于业务来说,这种更新或删除到底算是成功还是失败呢?还是大家根据自己的实际业务情况来确定吧!

总结

关于 PDO 和 PDOStatement 相关的内容就学习到这里了。我们完整地梳理了一遍它们两个所有的方法,也都进行了相关的测试。大家在日常使用中可能接触到的并不多,框架都已经为我们封装好了。不过对于学习来说,平常的小测试、小调试完全可以自己手写来加深记忆和理解。在深入理解了这些扩展类的使用方法后,反过来又能帮助我们更加的清楚框架是如何去封装它们的。总之,学习就是不断的从高层到底层,再从底层返回高层,循环往复,才能更加的得心应手。

测试代码:

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
Salin selepas log masuk

推荐学习:php视频教程

Atas ialah kandungan terperinci 三分钟带你了解PHP中的查询结构集. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Panduan Pemasangan dan Naik Taraf PHP 8.4 untuk Ubuntu dan Debian Panduan Pemasangan dan Naik Taraf PHP 8.4 untuk Ubuntu dan Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 membawa beberapa ciri baharu, peningkatan keselamatan dan peningkatan prestasi dengan jumlah penamatan dan penyingkiran ciri yang sihat. Panduan ini menerangkan cara memasang PHP 8.4 atau naik taraf kepada PHP 8.4 pada Ubuntu, Debian, atau terbitan mereka

Tarikh dan Masa CakePHP Tarikh dan Masa CakePHP Sep 10, 2024 pm 05:27 PM

Untuk bekerja dengan tarikh dan masa dalam cakephp4, kami akan menggunakan kelas FrozenTime yang tersedia.

Muat naik Fail CakePHP Muat naik Fail CakePHP Sep 10, 2024 pm 05:27 PM

Untuk mengusahakan muat naik fail, kami akan menggunakan pembantu borang. Di sini, adalah contoh untuk muat naik fail.

Bincangkan CakePHP Bincangkan CakePHP Sep 10, 2024 pm 05:28 PM

CakePHP ialah rangka kerja sumber terbuka untuk PHP. Ia bertujuan untuk menjadikan pembangunan, penggunaan dan penyelenggaraan aplikasi lebih mudah. CakePHP adalah berdasarkan seni bina seperti MVC yang berkuasa dan mudah difahami. Model, Pandangan dan Pengawal gu

Pengesah Mencipta CakePHP Pengesah Mencipta CakePHP Sep 10, 2024 pm 05:26 PM

Pengesah boleh dibuat dengan menambah dua baris berikut dalam pengawal.

Pembalakan CakePHP Pembalakan CakePHP Sep 10, 2024 pm 05:26 PM

Log masuk CakePHP adalah tugas yang sangat mudah. Anda hanya perlu menggunakan satu fungsi. Anda boleh log ralat, pengecualian, aktiviti pengguna, tindakan yang diambil oleh pengguna, untuk sebarang proses latar belakang seperti cronjob. Mengelog data dalam CakePHP adalah mudah. Fungsi log() disediakan

Cara Menyediakan Kod Visual Studio (Kod VS) untuk Pembangunan PHP Cara Menyediakan Kod Visual Studio (Kod VS) untuk Pembangunan PHP Dec 20, 2024 am 11:31 AM

Kod Visual Studio, juga dikenali sebagai Kod VS, ialah editor kod sumber percuma — atau persekitaran pembangunan bersepadu (IDE) — tersedia untuk semua sistem pengendalian utama. Dengan koleksi sambungan yang besar untuk banyak bahasa pengaturcaraan, Kod VS boleh menjadi c

Panduan Ringkas CakePHP Panduan Ringkas CakePHP Sep 10, 2024 pm 05:27 PM

CakePHP ialah rangka kerja MVC sumber terbuka. Ia menjadikan pembangunan, penggunaan dan penyelenggaraan aplikasi lebih mudah. CakePHP mempunyai beberapa perpustakaan untuk mengurangkan beban tugas yang paling biasa.

See all articles