您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關如何正確的使用mysqli_set_charset和SET NAMES,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
代碼如下:
//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) < MY_CS_NAME_SIZE &&
(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) < 40100)
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問題):
復制代碼 代碼如下:
<?php
$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) "慭"大家現在很清楚了吧?
上述就是小編為大家分享的如何正確的使用mysqli_set_charset和SET NAMES了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。