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) "慭"大家现在很清楚了吧?

Outils d'IA chauds

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

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

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

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

Sujets chauds

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

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();".

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.

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

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

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

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");

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
