Maison développement back-end tutoriel php mysqli_set_charset和SET NAMES使用抉择及优劣分析_php实例

mysqli_set_charset和SET NAMES使用抉择及优劣分析_php实例

May 17, 2016 am 09:07 AM
charset set

最近公司组织了个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) "慭"大家现在很清楚了吧?
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Explication détaillée de la fonction Définir la balise dans les balises SQL dynamiques MyBatis Explication détaillée de la fonction Définir la balise dans les balises SQL dynamiques MyBatis Feb 26, 2024 pm 07:48 PM

Interprétation des balises SQL dynamiques MyBatis : explication détaillée de l'utilisation des balises Set MyBatis est un excellent cadre de couche de persistance. Il fournit une multitude de balises SQL dynamiques et peut construire de manière flexible des instructions d'opération de base de données. Parmi elles, la balise Set est utilisée pour générer la clause SET dans l'instruction UPDATE, qui est très couramment utilisée dans les opérations de mise à jour. Cet article expliquera en détail l'utilisation de la balise Set dans MyBatis et démontrera ses fonctionnalités à travers des exemples de code spécifiques. Qu'est-ce que Set tag Set tag est utilisé dans MyBati

Comment supprimer des éléments de l'ensemble en javascript Comment supprimer des éléments de l'ensemble en javascript Jan 12, 2022 am 10:56 AM

Méthodes pour supprimer des éléments : 1. Utilisez delete() pour supprimer l'élément spécifié de l'objet Set, la syntaxe est "setObj.delete(value);" 2. Utilisez clear() pour supprimer tous les éléments de l'objet Set, le la syntaxe est "setObj.delete(value);" "setObj.clear();".

Inventaire des utilisations courantes de dict et set dans la programmation Python Inventaire des utilisations courantes de dict et set dans la programmation Python Jul 25, 2023 pm 04:52 PM

Cet article est basé sur les bases de Python et explique comment utiliser dict et set. Le dict utilisant la structure de stockage clé-valeur est très utile en Python. Il est important de choisir un objet immuable comme clé. est une chaîne.

Quelle est la différence entre la méthode set et la méthode add dans List en Java ? Quelle est la différence entre la méthode set et la méthode add dans List en Java ? Apr 19, 2023 pm 07:49 PM

Préface Il existe deux méthodes très similaires dans l'interface de collection couramment utilisée List en Java : Eset(intindex,Eelement);voidadd(intindex,Eelement); ces deux méthodes insèrent des éléments spécifiés à des positions spécifiées dans la collection, puis quelle est la différence ; entre ces deux méthodes ? Examinons ensuite les différences et les similitudes entre ces deux méthodes via ArrayList, notre implémentation de collection couramment utilisée. Tout d'abord, examinons les similitudes entre ces deux méthodes dans ArrayList. Elles inséreront de nouveaux éléments à des positions spécifiées dans le fichier. collection, comme l'exemple suivant : #Insérer un F en 2ème position de la collection #Insérer Listlist= via la méthode add

Comparaison de Java Map et d'autres frameworks de collecte : analyse des avantages et des inconvénients et guide de scénarios d'application Comparaison de Java Map et d'autres frameworks de collecte : analyse des avantages et des inconvénients et guide de scénarios d'application Feb 19, 2024 pm 10:24 PM

1. Présentation du cadre de collection Map Le cadre de collection Map est une structure de données de paire clé-valeur qui vous permet d'utiliser des clés pour rechercher et stocker des valeurs. Chaque clé de la Map est unique et ne peut être associée qu'à une seule valeur. Les implémentations courantes dans le cadre de collection Map incluent HashMap, TreeMap et LinkedHashMap. 1.HashMapHashMap est l'implémentation de Map la plus largement utilisée en Java. Elle stocke des données basées sur des tables de hachage. HashMap a d'excellentes performances et la complexité temporelle des opérations de recherche et d'insertion est O(1), mais cela ne garantit pas l'ordre des éléments. Code de démonstration : Mapmap=newHashMap

Comment implémenter la commande Set du client Tile intégré Springboot Comment implémenter la commande Set du client Tile intégré Springboot May 19, 2023 pm 01:37 PM

La syntaxe de la commande set SETkeyid[FIELDnamevalue...][EXseconds][NX|XX](OBJECTgeojson)|(POINTlatlonz)|(BOUNDSminlatminlonmaxlatmaxlon)|(HASHgeohash)|(STRINGvalue) La commande set est équivalente à l'utilisation de la commande hash dans Redis, c'est aussi une combinaison de clé et d'identifiant, mais la différence est que la commande set de Tile38 peut également contenir davantage d'autres attributs, tels que la personnalisation du champ FIELD, la définition de la période de validité EX, etc., alors nous devons

Utilisations courantes de l'ensemble Utilisations courantes de l'ensemble Oct 24, 2023 am 11:25 AM

Les utilisations courantes de set incluent la création d'un ensemble, l'ajout d'éléments, la suppression d'éléments, la détermination si l'ensemble est vide, l'obtention de la taille de l'ensemble, la traversée de l'ensemble, la recherche d'éléments et les opérations d'ensemble. Introduction détaillée : 1. Créez un ensemble, Setset=newHashSet(); 2. Ajoutez des éléments, set.add("java"); set.add("python");; 3. Supprimez des éléments, set.remove("java");

Structures de données PHP SPL : secrets pour améliorer les performances des applications Structures de données PHP SPL : secrets pour améliorer les performances des applications Feb 19, 2024 pm 11:12 PM

Concept des structures de données SPL PHPSPL (Standard PHP Library) contient un ensemble de structures de données et de classes d'itérateurs conçues pour améliorer les types de données natifs de PHP. Ces structures sont optimisées pour stocker et manipuler efficacement une variété de données et fournir une interface cohérente et un mécanisme d'itération flexible. Structures de données SPL de base La bibliothèque SPL fournit une variété de structures de données, notamment : LinkedList : une liste doublement chaînée qui permet une insertion, une suppression et une recherche rapides. Pile : structure de données dernier entré, premier sorti (LIFO) pour les opérations de pile. File d'attente : structure de données premier entré, premier sorti (FIFO) pour les opérations de file d'attente. Carte : une collection de paires clé-valeur, offrant une recherche de clé et un stockage de données efficaces. Ensemble : collection de valeurs uniques, prend en charge la recherche et la collecte rapides de membres

See all articles