搜索
首页后端开发php教程mysqli_set_charset和SET NAMES使用抉择及优劣分析_PHP教程

最近公司组织了个PHP安全编程的培训, 其中涉及到一部分关于Mysql的”SET NAMES”和mysql_set_charset (mysqli_set_charset)的内容:
说到, 尽量使用mysqli_set_charset(mysqli:set_charset)而不是”SET NAMES”, 当然, 这个内容在PHP手册中也有叙及, 但是却没有解释为什么.

最近有好几个朋友问我这个问题, 到底为什么?
问的人多了, 我也就觉得可以写篇blog, 专门介绍下这部分的内容了.
首先, 很多人都不知道”SET NAMES”到底是做了什么,
我之前的文章深入MySQL字符集设置中, 曾经介绍过character_set_client/character_set_connection/character_set_results这三个MySQL的”环境变量”, 这里再简单介绍下,
这三个变量, 分别告诉MySQL服务器, 客户端的编码集, 在传输给MySQL服务器的时候的编码集, 以及期望MySQL返回的结果的编码集.
比如, 通过使用”SET NAMES utf8″, 就告诉服务器, 我用的是utf-8编码, 我希望你也给我返回utf-8编码的查询结果.

一般情况下, 使用”SET NAMES”就足够了, 也是可以保证正确的. 那么为什么手册又要说推荐使用mysqli_set_charset(PHP>=5.0.5)呢?
首先, 我们看看mysqli_set_charset到底做了什么(注意星号注释处, mysql_set_charset类似):

复制代码 代码如下:

//php-5.2.11-SRC/ext/mysqli/mysqli_nonapi.c line 342
PHP_FUNCTION(mysqli_set_charset)
{
MY_MYSQL*mysql;
zval*mysql_link;
char *cs_name = NULL;
unsigned int len;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis()
, "Os", &mysql_link, mysqli_link_class_entry, &cs_name, &len) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL*, &mysql_link, "mysqli_link"
, MYSQLI_STATUS_VALID);
if (mysql_set_character_set(mysql->mysql, cs_name)) {
//** 调用libmysql的对应函数
RETURN_FALSE;
}
RETURN_TRUE;
}

那mysql_set_character_set又做了什么呢?
复制代码 代码如下:

//mysql-5.1.30-SRC/libmysql/client.c, line 3166:
int STDCALLmysql_set_character_set(MYSQL*mysql, const char *cs_name)
{
structcharset_info_st *cs;
const char *save_csdir= charsets_dir;
if (mysql->options.charset_dir)
charsets_dir= mysql->options.charset_dir;
if (strlen(cs_name) (cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY, MYF(0))))
{
char buff[MY_CS_NAME_SIZE + 10];
charsets_dir= save_csdir;
/* Skip execution of "SET NAMES" for pre-4.1 servers */
if (mysql_get_server_version(mysql) return 0;
sprintf(buff, "SET NAMES %s", cs_name);
if (!mysql_real_query(mysql, buff, strlen(buff)))
{
mysql->charset= cs;
}
}
//以下省略

我们可以看到, mysqli_set_charset除了做了”SET NAMES”以外, 还多做了一步:
复制代码 代码如下:

sprintf(buff, "SET NAMES %s", cs_name);
if (!mysql_real_query(mysql, buff, strlen(buff)))
{
mysql->charset= cs;
}

而对于mysql这个核心结构的成员charset又有什么作用呢?
这就要说说mysql_real_escape_string()了, 这个函数和mysql_escape_string的区别就是, 它会考虑”当前”字符集. 那么这个当前字符集从哪里来呢?
对了, 你猜的没错, 就是mysql->charset.
mysql_real_string在判断宽字符集的字符的时候, 就根据这个成员变量来分别采用不同的策略, 比如如果是utf-8, 那么就会采用libmysql/ctype-utf8.c.
看个实例, 默认mysql连接字符集是latin-1, (经典的5c问题):
复制代码 代码如下:

$db = mysql_connect('localhost:3737', 'root' ,'123456');
mysql_select_db("test");
$a = "\x91\x5c";//"慭"的gbk编码, 低字节为5c, 也就是ascii中的"\"
var_dump(addslashes($a));
var_dump(mysql_real_escape_string($a, $db));
mysql_query("set names gbk");
var_dump(mysql_real_escape_string($a, $db));
mysql_set_charset("gbk");
var_dump(mysql_real_escape_string($a, $db));
?>

因为, “慭”的gbk编码低字节为5c, 也就是ascii中的”\”, 而因为除了mysql(i)_set_charset影响mysql->charset以外, 其他时刻mysql->charset都为默认值, 所以, 结果就是:
复制代码 代码如下:

$ php -f 5c.php
string(3) "慭\"
string(3) "慭\"
string(3) "慭\"
string(2) "慭"大家现在很清楚了吧?

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/326354.htmlTechArticle最近公司组织了个PHP安全编程的培训, 其中涉及到一部分关于Mysql的”SET NAMES”和mysql_set_charset (mysqli_set_charset)的内容: 说到, 尽量使用mysqli...
声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
详解MyBatis动态SQL标签中的Set标签功能详解MyBatis动态SQL标签中的Set标签功能Feb 26, 2024 pm 07:48 PM

MyBatis动态SQL标签解读:Set标签用法详解MyBatis是一个优秀的持久层框架,它提供了丰富的动态SQL标签,可以灵活地构建数据库操作语句。其中,Set标签是用于生成UPDATE语句中SET子句的标签,在更新操作中非常常用。本文将详细解读MyBatis中Set标签的用法,以及通过具体的代码示例来演示其功能。什么是Set标签Set标签用于MyBati

PHP Fatal error: Call to undefined function mysqli_connect()的解决方法PHP Fatal error: Call to undefined function mysqli_connect()的解决方法Jun 23, 2023 am 09:40 AM

在使用PHP编写Web应用程序时,经常会使用MySQL数据库来存储数据。PHP提供了一种与MySQL数据库进行交互的方法,称为MySQLi。然而,有时在使用MySQLi时,会遇到一个错误信息,如以下所示:PHPFatalerror:Calltoundefinedfunctionmysqli_connect()这个错误信息意味着PHP无法找到my

华硕主板与R55600(包括R55600u和5600h)兼容的选择华硕主板与R55600(包括R55600u和5600h)兼容的选择Jan 02, 2024 pm 05:32 PM

R55600搭配华硕哪个主板华硕ROGStrixB550-FGaming主板是一个非常出色的选择。它与Ryzen55600X处理器完美兼容,并提供出色的性能和功能。该主板具备可靠的供电系统,可支持超频,并提供丰富的扩展插槽和端口,满足日常使用和游戏需求。ROGStrixB550-FGaming还配备了高品质的音频解决方案、快速的网络连接和可靠的散热设计,确保系统保持高效稳定。此外,该主板还采用了华丽的ROG风格,配备了华丽的RGB照明效果,为您的计算机增添了视觉享受。总而言之,华硕ROGStri

php无法连接mysqli怎么办php无法连接mysqli怎么办Nov 09, 2022 am 10:07 AM

php无法连接mysqli的解决办法:1、打开“php.ini”文件;2、找到“mysqli.reconnect”;3、将“mysqli.reconnect = OFF”改成“mysqli.reconnect = on”即可。

PHP PDO 与 mysqli:比较和对比PHP PDO 与 mysqli:比较和对比Feb 19, 2024 pm 12:24 PM

PDOPDO是一个面向对象的数据库访问抽象层,它为PHP提供了一个统一的接口,允许您使用相同的代码与不同的数据库(如Mysql、postgresql、oracle)进行交互。PDO隐藏了底层数据库连接的复杂性,简化了数据库操作。优缺点优点:统一接口,支持多种数据库简化数据库操作,降低开发难度提供预处理语句,提高安全性支持事务处理缺点:性能可能比原生扩展稍低依赖外部库,可能会增加开销演示代码使用PDO连接mysql数据库:$db=newPDO("mysql:host=localhost;dbnam

赛扬g4900与i36100相比哪个更优?(赛扬g4900与i34170相比哪个更优?)赛扬g4900与i36100相比哪个更优?(赛扬g4900与i34170相比哪个更优?)Jan 01, 2024 pm 06:01 PM

赛扬g4900和i36100哪个好当涉及到赛扬G4900和I36100这两款处理器时,毫无疑问,I36100的性能更胜一筹。赛扬处理器通常被视为低端处理器,主要用于廉价笔记本电脑。而I3处理器则主要用于高端处理器,其性能非常出色。不论是玩游戏还是观看视频,使用I3处理器都不会出现任何卡顿情况。因此,如果你有可能,尽量选择购买英特尔I系列处理器,特别是用于台式机,这样你就能畅享网络世界的乐趣了。赛扬G4900T性能怎么样从性能方面来看,奔腾G4900T在频率方面表现出色,相比之前的版本,CPU性能

mysql的运行文件是什么mysql的运行文件是什么Apr 11, 2023 am 10:38 AM

mysql的运行文件是mysqld;mysqld是一个可执行文件,代表着Mysql服务器程序,执行这个文件可以直接启动一个服务器进程;而mysqld_safe是一个启动脚本,它会间接调用mysqld,并且还会顺带启动一个监控进程。

PHP Warning: mysqli_connect(): (HY000/2002): Connection refused的解决方法PHP Warning: mysqli_connect(): (HY000/2002): Connection refused的解决方法Jun 23, 2023 am 08:54 AM

如果你使用PHP连接MySQL数据库时遇到了以下错误提示:PHPWarning:mysqli_connect():(HY000/2002):Connectionrefused那么你可以尝试按照下面的步骤来解决这个问题。确认MySQL服务是否正常运行首先应该检查MySQL服务是否正常运行,如果服务未运行或者启动失败,就可能会导致连接被拒绝的错误。你可

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尊渡假赌尊渡假赌尊渡假赌

热工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

SecLists

SecLists

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

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版