虽然是一些稀有的属性方法,但是很多同学在日常开发中可能还是会用到。这只是一个学习,可能是比较少用到的mysqli的一些属性或方法。将其视为扩展您的知识库。切换用户,首先要切换当前连接数据库的用户。//切换用户$mysqli->change_user('root2',"123",'blog_test');//错误信息$res=$mysqli->query("SELECT*FROMzyblog_test_user");var_dump($res);//bool(false)var_dump($mysqli->error_list);//array(1){//[0]=>//array(3){//["errno"]=>//int(1142)//["sqlstate"]=>//string(5)"42000"//["error"]=>//string(78)"SELECT命令拒绝用户'root2'@'localhost'用于表'zyblog_test_user'"//}//}在mysqli对象实例化后,使用change_user()方法可以方便的切换用户。这段代码中,我们的root2用户对blog_test表没有SELECT权限,所以返回的query()查询结果为空。通过打印mysqli的error_list属性可以看到当前的错误信息。错误消息跟在上一段之后。对于执行语句的错误信息,我们可以通过mysqli中的几个属性来获取。比如上面的error_list。它包含了所有错误信息的列表,并且是非常详细的错误信息内容。但是,我们也可以通过另外两个属性获取个别的错误号和错误信息字符串。var_dump($mysqli->errno);//int(1142)var_dump($mysqli->error);//string(78)"SELECTcommanddeniedtouser'root2'@'localhost'fortable'zyblog_test_user'"errno属性存储数据库的错误号,error属性存储错误信息的详细文本描述。这两条错误信息的内容是执行SQL语句后数据库返回的内容。连接错误信息当然,如果在连接数据库时出现错误,我们也可以通过connect_errno和connect_error获取它们的错误号和错误信息内容。$mysqli2=@newmysqli("xxx","root","","blog_test");var_dump($mysqli2->connect_errno);//int(2002)var_dump($mysqli2->connect_error);//string(90)"php_network_getaddresses:getaddrinfofailed:nodenamenorservnameprovided,ornotknown"在这段代码中,我们使用了错误的主机信息。如果在实例化的时候不加错误抑制器,那么在实例化的时候会报PHP警告信息Warning。这里我们添加错误抑制器以测试输出的清晰度。客户端连接统计var_dump($mysqli->get_connection_stats());//array(163){//["bytes_sent"]=>//string(3)"306"//["bytes_received"]=>//string(3)"287"//["packets_sent"]=>//string(2)"10"//["packets_received"]=>//string(1)"6"//["protocol_overhead_in"]=>//string(2)"24"//["protocol_overhead_out"]=>//string(2)"40"//["bytes_received_ok_packet"]=>//string(1)"0"//["bytes_received_eof_packet"]=>//string(1)"0"//...//...//["bytes_received_real_data_normal"]=>//string(1)"0"//["bytes_received_real_data_ps"]=>//string(1)"0"//}通过get_connection_stats()方法,我们可以得到当前数据库连接的一些统计信息。返回的内容很多,每个字段都没有官方文档。不过我们还是可以从字段名中看出一些有用的信息,比如bytes_sent发送的字节数,bytes_received接收的字节数。字符集这几年,我们基本都是使用UTF-8作为PHP+MySQL开发的默认字符集编码。不过在早期,包括Discuz、DedeCMS在内的早期开源建站程序都提供了一套UTF-8和一套GBK源码供大家使用。而mysqli可以方便快捷的获取和切换当前数据库使用的字符集。获取数据库字符//获取数据库字符var_dump($mysqli->character_set_name());//string(4)"utf8"character_set_name()不要以为看到一个set关键字就是设置或者修改什么的,这个方法是获取当前的字符集信息。字符集详细信息var_dump($mysqli->get_charset());//object(stdClass)#2(8){//["charset"]=>//string(4)"utf8"//["collat??ion"]=>//string(15)"utf8_general_ci"//["dir"]=>//string(0)""//["min_length"]=>//int(1)//["max_length"]=>//int(3)//["number"]=>//int(33)//["state"]=>//int(1)//["comment"]=>//string(13)"UTF-8Unicode"//}我们还可以通过get_charset()获取当前数据库连接的详细字符集信息。其中,charset为字符类型。这里使用UTF-8类型,字符集为utf8_general_ci。这套基本是我们目前开发的标准配置。设置字符集$mysqli->set_charset('gbk');$mysqli->query("insertintozyblog_test_user(username,password,salt)values('GBKcharacter','dd','d')");var_dump($mysqli->错误);//string(65)"Incorrectstringvalue:'\xAC\xA6'forcolumn'username'atrow1"$mysqli->set_charset('utf8');$mysqli->query("insertintozyblog_test_user(username,password,salt)values('UTFcharacter','dd','d')");var_dump($mysqli->error);echo$mysqli->insert_id,PHP_EOL;通过set_charset()方法可以设置当前数据库连接的字符。在第一段代码中,我们设置连接字符为gbk,然后执行insert语句,会直接返回字符不匹配的信息。特殊字符转义说完了字符的问题,我们再顺便提一个SQL注入的问题。除了使用预处理功能解决SQL注入外,MySQLi还为我们提供了real_escape_string()方法,可以手动解决SQL语句中的一些特殊符号问题。$username="aaa'bbb";$username=$mysqli->real_escape_string($username);var_dump($username);//string(10)"aaa\'bbb"使用这个方法可以说和addslashes()方法类似,但是比addslashes()方法转义了更多的内容,包括:NUL(ASCII0),\n,\r,\,',"和Control-Z字符。线程操作关于MySQL线程的问题,以后深入学习和刷MySQL文档的时候再说(因为我现在不是很清楚~~)。在这里,我们来看看mysqli中MySQL线程的几个属性和方法。var_dump($mysqli->thread_safe);//NULLvar_dump($mysqli->thread_id);//int(600)$thread_id=$mysqli->thread_id;$mysqli->kill($thread_id);if(!$mysqli->query("insertintozyblog_test_user(username,password,salt)values('killthread','dd','d')")){var_dump($mysqli->error);//string(26)"MySQLserverhasgoneaway"}thread_safe属性是保存的当前数据库连接是否线程安全。在我们的测试中,返回NULL而不是正常的布尔值。我们将在未来学习这一点。thread_id属性保存当前连接的线程ID。通过这个线程ID,我们可以使用另一个kill()方法来杀死当前线程。其实相当于关闭了当前mysqli对象的连接。这时,当我们使用这个连接对象进行其他操作时,就会出现MySQLserverhasgoneaway的提示信息。其实上面提到的很多mysqli对象上的属性都可以通过打印mysqli对象直接查看。var_dump($mysqli);//object(mysqli)#1(19){//["affected_rows"]=>//int(1)//["client_info"]=>//string(79)"mysqlnd5.0.12-dev-20150407-$Id:7cc7cc96e675f6d72e5cf0f267f48e167c2abb23$"//["client_version"]=>//int(50012)//["connect_errno"]=>//int(2002)//["connect_error"]=>//string(90)"php_network_getaddresses:getaddrinfofailed:nodenamenorservnameprovided,ornotknown"//["errno"]=>//int(0)//["error"]=>//string(0)""//["error_list"]=>//array(0){//}//["field_count"]=>//int(0)//["host_info"]=>//string(25)"LocalhostviaUNIXsocket"//["info"]=>//NULL//["insert_id"]=>//int(59)//["server_info"]=>//string(6)"8.0.17"//["server_version"]=>//int(80017)//["stat"]=>//string(139)"正常运行时间:355128线程:4问题:35696慢查询:0打开:764刷新表:3打开的表:每秒636次查询平均:0.100"//["sqlstate"]=>//string(5)"00000"//["protocol_version"]=>//int(10)//["thread_id"]=>//int(606)//["warning_count"]=>//int(0)//}像host_info显示的是我们连接数据库的主机信息,server_info是连接的数据库版本信息,就像我们这里使用的MySQL8stat的简单统计信息,可以看到有4个线程,没有慢查询等,大家可以仔细研究一下这个对象中的这些属性,也许有些内容是你实际需要的项目。总结一下今天的文章,我们将学习一些简单的mysqli类持有的属性和方法。我们还没有正式开始学习查询等语句,但是从这些属性和方法中可以看出,与PDO相比,提供的功能bymysqli确实比较全面,我们会继续深入研究探索mysqli的各种方法和使用,测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/5。PHP中MySQLi扩展学习(二)mysqli类的一些稀有属性方法。PHP参考文档:https://www.php.net/manual/zh/book.mysqli.php各媒体平台均可搜索【硬核项目经理】
