php中的mysqli扩展学习mysqli的基本操作(代码片段)

硬核项目经理 硬核项目经理     2022-12-01     639

关键词:

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

连接与选择数据库

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

$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

参考文档:

https://www.php.net/manual/zh/book.mysqli.php

关注公众号:【硬核项目经理】获取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料

知乎、公众号、抖音、头条搜索【硬核项目经理】

B站ID:482780532

php中的mysqli扩展学习mysqli类的一些少见的属性方法(代码片段)

虽说是少见的一些属性方法,但是可能还是有不少同学在日常的开发中使用过,这里只是学习了可能相对来说我们用得比较少的一些mysqli的属性或方法。就当是扩展一下自己的知识体系。切换用户首先就是切换一下当前连接数据... 查看详情

php中的mysqli扩展学习mysqli的事务与预处理语句(代码片段)

对于MySQLi来说,事务和预处理语句当然是它之所以能够淘汰MySQL(原始)扩展的资本。我们之前也已经学习过了PDO中关于事务和预处理语句相关的内容。所以在这里,我们就不再多讲理论方面的东西了,直接上代码来看看MySQLi中... 查看详情

使用 PHP7 在 MariaDB 中的 MySQLi 和 PDO

】使用PHP7在MariaDB中的MySQLi和PDO【英文标题】:MySQLiandPDOinmariaDBwithPHP7【发布时间】:2018-12-2304:50:00【问题描述】:我刚刚开始学习一些PHP/MySQL(以及一般的编程)。我主要使用在这里找到的文档:https://www.w3schools.com/php/php_mysql_i... 查看详情

phpMyAdmin - 错误:缺少 mysqli 扩展 [关闭]

】phpMyAdmin-错误:缺少mysqli扩展[关闭]【英文标题】:phpMyAdmin-Error:Themysqliextensionismissing[closed]【发布时间】:2017-11-2012:43:13【问题描述】:就像标题说的那样,自从我在基本操作系统上安装了php7(我没有从php5升级)以来,我在... 查看详情

腾讯云服务器下,怎么安装php的mysqli扩展

...1、进入php源代码目录:#cd/tmp/php-5.x.x/2、再进入要添加的mysqli扩展源码目录:#cdext/mysqli/2、调用已经编译好的php里面的phpize:#/usr/local/php/bin/phpize3、然后configure:#./configure--with-php-config=/usr/local/php/bin/php-config--with-mysqli=/usr/local/mysq... 查看详情

最近在学习php,其中使用了mysqli扩展,注意是mysqli不是mysql(因php7已经不支持mysql扩展了)。

...么破?A.php<?php include_once($rootpath.'B.php'); $conn=newmysqli($mysql_host,$mysql_user,$mysql_pass,$mysql_db); if(mysqli_connect_errno())echo"连接数据库失败"; if(!$conn) switch(mysqli_connect_errno()) case1040: case2002: die("<html><head>... 查看详情

如何在php中扩展mysqli插件。

如何在php中扩展mysqli插件。Mysqli是php5之后才有的功能,没有开启扩展的可以打开php.ini的配置文件查找下面的语句:;extension=php_mysqli.dll将其修改为:extension=php_mysqli.dll即可。相对于mysql有很多新的特性和优势(1)支持本地绑定、... 查看详情

缺少 mysqli 扩展

】缺少mysqli扩展【英文标题】:mysqiextensionismissing【发布时间】:2011-10-0709:14:51【问题描述】:我在PHP配置文件中取消了“extension=php_mysqli.dll”的注释,但我仍然收到我的mySQLi扩展丢失的错误消息。我还要验证什么?【问题讨论... 查看详情

编辑 php.ini 文件以包含 mysqli 的扩展名

】编辑php.ini文件以包含mysqli的扩展名【英文标题】:Editphp.iniFiletoincludeextensionformysqli【发布时间】:2016-08-2518:39:21【问题描述】:所以,我正在尝试在php程序中使用表,但我遇到了一个致命错误(未找到类mysqli),在对***进行... 查看详情

缺少 mysqli 扩展。请检查您的 PHP 配置

】缺少mysqli扩展。请检查您的PHP配置【英文标题】:Themysqliextensionismissing.PleasecheckyourPHPconfiguration【发布时间】:2012-05-2516:12:28【问题描述】:我浏览了所有可以找到与此问题和我的问题相关的论坛,但没有任何效果。我有apache2... 查看详情

缺少 mysqli 扩展。请检查您的 PHP 配置

】缺少mysqli扩展。请检查您的PHP配置【英文标题】:Themysqliextensionismissing.PleasecheckyourPHPconfiguration【发布时间】:2021-07-2102:53:58【问题描述】:我浏览了所有可以找到与此问题和我的问题相关的论坛,但没有任何效果。我有apache2... 查看详情

“缺少 mysqli 扩展”,但它位于扩展目录中

...】:我正在设置PHPMyAdmin以在IIS8上运行。我已按照本教程中的步骤操作:http://www.php.net/manual/en/install.window 查看详情

在这个 php 配置中是不是启用了 mysqli 扩展?

】在这个php配置中是不是启用了mysqli扩展?【英文标题】:Ismysqliextensionenabledinthisphpconfiguration?在这个php配置中是否启用了mysqli扩展?【发布时间】:2011-09-1105:23:47【问题描述】:我有一个用php设计的网站,带有mysqli(mysql-改进... 查看详情

为啥登陆phpadmin的界面提示缺少mysqli扩展,请检查php配置

phpinfo()查看下是否有mysqli这个扩展,没有的话,去php安装目录下查看是否有mysqli.dll这个插件,没有的话,请去官方下载对应版本的扩展,如果有那么,查看php.ini有没有开启extension=php_mysqli.dll如果没找到添加这句,重启apache服务... 查看详情

在 PHP 中,啥对应于 MySQLi 中的 mysql.connect_timeout?

】在PHP中,啥对应于MySQLi中的mysql.connect_timeout?【英文标题】:InPHP,whatcorrespondstomysql.connect_timeoutinMySQLi?在PHP中,什么对应于MySQLi中的mysql.connect_timeout?【发布时间】:2011-06-2202:10:31【问题描述】:我们最近移植了一些代码,我... 查看详情

php安装缺少mysqli扩展的原因及解决方法

1.检查php.iniextension=php_mysqli.dll是不是已经启用也就是去掉前面的;2.检查php.iniextension_dir地址是不是指向了php目录的ext目录下3.检查lib_mysql.dll有没有拷贝到windows目录下4.检查php安装目录ext目录下,php_mysqli.dll文件是不是存在5.查看php... 查看详情

验证mysqli扩展是否

<?php//createTime:2016/9/921:57//验证mySqli扩展是否//phpinfo();//2.检测扩展是否已经加载//var_dump(extension_loaded(‘mysqli‘));//bool(true)//3.检测函数是否存在var_dump(function_exists(‘mysqli_connect‘));//4得到当前已经开启的扩展print 查看详情

如何在 PHP 7 中启用 MySQLi 扩展?

】如何在PHP7中启用MySQLi扩展?【英文标题】:HowcanIenabletheMySQLiextensioninPHP7?【发布时间】:2016-05-2706:50:16【问题描述】:我已经在Ubuntu14.04(TrustyTahr)上安装了PHP7和MySQL5.5.47。我使用以下方法检查了已安装的扩展程序:sudoapt-cachesea... 查看详情