搜索
首页后端开发PHP问题PHP中mysqli的基本操作有哪些

MySQLi的扩展相对于PDO来说功能更加的丰富,所以我们依然还会在学习过程中穿插各种MySQLi中好玩的方法函数。不过,今天的主角是MySQLi中如何执行SQL语句以及多条SQL语句的执行。

PHP中mysqli的基本操作有哪些

连接与选择数据库

首先是一个小内容的学习分享,依然还是连接数据库,不过这次我们用另外一种方式来进行连接。

$mysqli = new mysqli();
$mysqli->real_connect("localhost", "root", "", "blog_test");

var_dump($mysqli); 
// ["thread_id"]=>
// int(163)

$mysqli->real_connect("localhost", "root2", "123", "blog_test");
var_dump($mysqli);
// ["thread_id"]=>
// int(164)

首先,我们实例化了一个 mysqli 对象。在实例化过程中,我们并没有给 mysqli 的构造函数传递任何的参数,而是使用 real_connect() 方法来传递数据库服务器信息并建立连接。

相信不少朋友从代码中就可以看出,我们使用 real_connect() 可以在一个 mysqli 实例下来切换不同的数据库连接。通过打印 mysqli 对象的内容就可以看出,两个连接的线程ID不同,也就是说,它们是不同的两个连接,但是使用的都是最上面所初始化的那个 mysqli 对象。

连接可以切换了,那么我们要连接的数据库呢?当然也可以方便地切换。

$mysqli->select_db('mysql');

就是这样一个简单的 select_db() 方法,就可以帮助我们在代码执行过程中动态地修改所连接的数据库。

执行 SQL 语句

对于 PDO 来说,如果是查询语句,我们需要使用 query() 方法,如果是增、删、改之类的其它语句,我们要使用 exec() ,通过这两个方法分别执行不同的 SQL 语句。但是在 MySQLi 中,我们统一只使用 query() 方法就可以了。

$mysqli->query("insert into zyblog_test_user(username, password, salt) values('3a', '3a', '3a')");
var_dump($mysqli->affected_rows);
var_dump($mysqli->insert_id);

$mysqli->query("update zyblog_test_user set password='3aa' where username='3a'");
var_dump($mysqli->affected_rows);

$mysqli->query("delete from zyblog_test_user where id = 60");
var_dump($mysqli->affected_rows);

$res = $mysqli->query("select * from zyblog_test_user where username='3a'");
print_r($res);
// mysqli_result Object
// (
//     [current_field] => 0
//     [field_count] => 4
//     [lengths] =>
//     [num_rows] => 3
//     [type] => 0
// )

print_r($res->fetch_assoc());
// Array
// (
//     [id] => 61
//     [username] => 3a
//     [password] => 3aa
//     [salt] => 3a
// )

while ($row = $res->fetch_assoc()) {
    print_r($row);
}
// Array
// (
//     [id] => 62
//     [username] => 3a
//     [password] => 3aa
//     [salt] => 3a
// )
// Array
// (
//     [id] => 63
//     [username] => 3a
//     [password] => 3aa
//     [salt] => 3a
// )
// ……

对于增、删、改之类的语句,query() 方法只会返回一个布尔值,也就是语句是否执行成功。记住,它返回的不是受影响的行数,这一点是需要注意的。我们如果需要获取受影响的行数需要使用 MySQLi 的属性 affected_rows 。对于插入语句来说,获取最新插入的数据ID使用的是 insert_id 属性。

如果执行的是 SELECT 语句,那么 query() 返回的就是一个 mysqli_result 对象,它代表从一个数据库查询中获取的结果集。关于这个对象的内容我们将在后面的文章中进行详细的说明。

执行多条 SQL 语句

执行多条 SQL 语句的能力对于 PDO 来说是无法实现的,不过据说 PDO 是支持的,语句是可以正常执行的,但是我们拿不到完整的返回结果。

$sql = "insert into zyblog_test_user(username, password, salt) values('3bb', '3bb', '3bb');"
        . "update zyblog_test_user set password='3aa' where username='3a';"
        . "select * from zyblog_test_user where username='3b';"
        . "select now()";

$pdo = new PDO("mysql:dns=locahost;dbname=blog_test", 'root', '', [PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION]);
$res = $pdo->exec($sql);
var_dump($res); // int(1)
$stmt = $pdo->query($sql);
foreach ($stmt as $row) { //PHP Fatal error:  Uncaught PDOException: SQLSTATE[HY000]: General error in
    var_dump($row);
}

从代码中可以看出,如果使用的是 exec() 方法,那么返回的就是 INSERT 语句的结果。如果使用 query() 方法,返回的虽然是 PDOStatement 对象,但是它是无法遍历的。

接下来我们就看看 MySQLi 是如何来执行这个多条语句拼接在一起的 SQL 语句的。

$mysqli->multi_query($sql);
$i = 1;
do{
    echo '第' . $i . '条:', PHP_EOL;
    $i++;
    $result = $mysqli->use_result();
    var_dump($result);
    var_dump($mysqli->affected_rows);
    if(is_object($result)){
        var_dump($result->fetch_assoc());
    }
    var_dump($mysqli->next_result());
    echo '========', PHP_EOL;
} while($mysqli->more_results() );
// 第1条:
// bool(false)
// int(1)
// ========
// 第2条:
// bool(false)
// int(0)
// ========
// 第3条:
// object(mysqli_result)#2 (5) {
//   ["current_field"]=>
//   int(0)
//   ["field_count"]=>
//   int(4)
//   ["lengths"]=>
//   NULL
//   ["num_rows"]=>
//   int(0)
//   ["type"]=>
//   int(1)
// }
// int(-1)
// array(4) {
//   ["id"]=>
//   string(2) "67"
//   ["username"]=>
//   string(2) "3b"
//   ["password"]=>
//   string(2) "3b"
//   ["salt"]=>
//   string(2) "3b"
// }
// ========
// 第4条:
// bool(false)
// int(0)
// ========

multi_query() 就是 MySQLi 提供的执行多条 SQL 语句的方法。通过它执行之后,返回的结果是一个布尔值,如果第一条语句就有问题的话,那么它返回的就是 FALSE 。如果是后面的语句错误了,我们需要调用 next_result() 才能获取后面语句的错误信息。

其实这也引出了我们 next_result() 这个方法的作用。它就相当于是为执行获取下一个结果的操作做准备,也可以看作是将游标移动到了下一条 SQL 语句上。而 more_results() 方法就是判断是否还有更多的语句没有执行。

use_result

在上面的测试代码中,获得每一条语句的执行结果使用的是 use_result() 这个方法。它的作用是启动结果集的检索。也就是说,在 mutli_query() 的时候,这些语句并没有马上执行,而是在调用 use_result() 时,才会执行当前的这条语句。我们注意到 INSERT 、 UPDATE 语句返回的结果都是 FALSE 。而且 SELECT 语句中的 num_rows 也是 0 。这就是它的特点,它也并没有直接将结果集的信息保存在程序的内存中。所以,use_result() 方法最大的好处就是占用内存小,适合大量查询的遍历,缺点则是每次都要去数据库查询,速度慢。

store_result

除了 use_result() 之外,还有一个 store_result() 方法可以帮助我们获得查询的结果集。它和 use_result() 方法是相反的,也就是说,它是直接执行就将结果集保存在内存中了。

$mysqli = new mysqli("localhost", "root", "", "blog_test");

$mysqli->multi_query($sql);
$i = 1;
do{
    echo '第' . $i . '条:', PHP_EOL;
    $i++;
    $result = $mysqli->store_result();
    var_dump($result);
    var_dump($mysqli->affected_rows);
    if(is_object($result)){
        var_dump($result->fetch_assoc());
    }
    var_dump($mysqli->next_result());
    echo '========', PHP_EOL;
}
while($mysqli->more_results() );
// 第1条:
// bool(false)
// int(1)
// ========
// 第2条:
// bool(false)
// int(0)
// ========
// 第3条:
// object(mysqli_result)#1 (5) {
//   ["current_field"]=>
//   int(0)
//   ["field_count"]=>
//   int(4)
//   ["lengths"]=>
//   NULL
//   ["num_rows"]=>
//   int(7)
//   ["type"]=>
//   int(0)
// }
// int(7)
// array(4) {
//   ["id"]=>
//   string(2) "67"
//   ["username"]=>
//   string(2) "3b"
//   ["password"]=>
//   string(2) "3b"
//   ["salt"]=>
//   string(2) "3b"
// }
// ========
// 第4条:
// object(mysqli_result)#3 (5) {
//   ["current_field"]=>
//   int(0)
//   ["field_count"]=>
//   int(1)
//   ["lengths"]=>
//   NULL
//   ["num_rows"]=>
//   int(1)
//   ["type"]=>
//   int(0)
// }
// int(1)
// array(1) {
//   ["now()"]=>
//   string(19) "2020-09-14 10:31:37"
// }

不仅查询结果中的 num_rows 有数据了,最后一条 SELECT now(); 语句也成功返回了。它和我们日常使用 query() 的结果是类似的。

另外需要注意的一点是,大家可以看一下我们执行这两条获取结果方式的循环条件是如何写得。more_results() 和 next_result() 针对这两种结果集的获取方式也是不同的,大家可以自己测一下。

总结

光说不练假把式,虽说多语句执行看似很美好,但即使在这简单的测试代码中,也会出现各种问题,大家一定要自己多尝试一下。在日常的开发过程中,最好还是一条一条的语句来执行,避免出现各种无法查明的问题而影响我们正常的业务执行。至于到底要不要使用这个能力,还是大家仁者见仁智者见智了。

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/6.PHP中的MySQLi扩展学习(三)mysqli的基本操作.php

推荐学习:php视频教程

以上是PHP中mysqli的基本操作有哪些的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:segmentfault。如有侵权,请联系admin@php.cn删除
酸与基本数据库:差异和何时使用。酸与基本数据库:差异和何时使用。Mar 26, 2025 pm 04:19 PM

本文比较了酸和基本数据库模型,详细介绍了它们的特征和适当的用例。酸优先确定数据完整性和一致性,适合财务和电子商务应用程序,而基础则侧重于可用性和

PHP安全文件上传:防止与文件相关的漏洞。PHP安全文件上传:防止与文件相关的漏洞。Mar 26, 2025 pm 04:18 PM

本文讨论了确保PHP文件上传的确保,以防止诸如代码注入之类的漏洞。它专注于文件类型验证,安全存储和错误处理以增强应用程序安全性。

PHP输入验证:最佳实践。PHP输入验证:最佳实践。Mar 26, 2025 pm 04:17 PM

文章讨论了PHP输入验证以增强安全性的最佳实践,重点是使用内置功能,白名单方法和服务器端验证等技术。

PHP API率限制:实施策略。PHP API率限制:实施策略。Mar 26, 2025 pm 04:16 PM

本文讨论了在PHP中实施API速率限制的策略,包括诸如令牌桶和漏水桶等算法,以及使用Symfony/Rate-limimiter之类的库。它还涵盖监视,动态调整速率限制和手

php密码哈希:password_hash和password_verify。php密码哈希:password_hash和password_verify。Mar 26, 2025 pm 04:15 PM

本文讨论了使用password_hash和pyspasswify在PHP中使用密码的好处。主要论点是,这些功能通过自动盐,强大的哈希算法和SECH来增强密码保护

OWASP前10 php:描述并减轻常见漏洞。OWASP前10 php:描述并减轻常见漏洞。Mar 26, 2025 pm 04:13 PM

本文讨论了OWASP在PHP和缓解策略中的十大漏洞。关键问题包括注射,验证损坏和XSS,并提供用于监视和保护PHP应用程序的推荐工具。

PHP XSS预防:如何预防XSS。PHP XSS预防:如何预防XSS。Mar 26, 2025 pm 04:12 PM

本文讨论了防止PHP中XSS攻击的策略,专注于输入消毒,输出编码以及使用安全增强的库和框架。

PHP接口与抽象类:何时使用。PHP接口与抽象类:何时使用。Mar 26, 2025 pm 04:11 PM

本文讨论了PHP中接口和抽象类的使用,重点是何时使用。界面定义了无实施的合同,适用于无关类和多重继承。摘要类提供常见功能

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境