国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

mysqli_set_charset和SET NAMES優劣分析

2024-07-24 12:38:22
字體:
來源:轉載
供稿:網友

本文章來分析一下關于mysqli_set_charset和SET NAMES吧,有需要學習的朋友可參考參考,我最常用會用set names來解決php與mysql亂碼問題.

程序設置,代碼如下:

mysql_query("SET NAMES UTF8");

my.ini設置

  1. # CLIENT SECTION 
  2.  
  3. [mysql] 
  4.  
  5. default-character-set=utf8 
  6.  
  7. # SERVER SECTION 
  8.  
  9. [mysqld] 
  10.  
  11. default-character-set=utf8 

這兩個字段來更改數據庫的默認字符集。第一個是客戶端默認的字符集,第二個是服務器端默認的字符集。假設我們把兩個都設為utf8,然后在MySQL Command Line Client里面輸入“show variebles like“character_set_%”;”,可看到如下字符:

  1. character_set_client   latin1 
  2. character_set_connection    latin1 
  3. character_set_database     utf8 
  4. character_set_results    latin1 
  5. character_set_server   utf8 
  6. character_set_system     utf8 

其中的utf8隨著我們上面的設置而改動。此時,要是我們通過采用UTF-8的PHP程序從數據庫里讀取數據,很有可能是一串“?????”或者是其他亂碼。網上查了半天,解決辦法倒是簡單,在連接數據庫之后,讀取數據之前,先執行一項查詢“SET NAMES UTF8”,即在PHP里為即可顯示正常(只要數據庫里信息的字符正常)。為什么會這樣?這句查詢“SET NAMES UTF8”到底是什么作用?

到MySQL命令行輸入“SET NAMES UTF8;”,然后執行“show variebles like“character_set_%”;”,發現原來為latin1的那些變量“character_set_client”、“character_set_connection”、“character_set_results”的值全部變為utf8了,原來是這3個變量在搗蛋。查閱手冊,上面那句等于:

  1. SET character_set_client = utf8; 
  2.  
  3. SET character_set_results = utf8; 
  4.  
  5. SET character_set_connection = utf8; 

這里要聲明一點,“SET NAMES UTF8”作用只是臨時的,MySQL重啟后就恢復默認了。

接下來就說到MySQL在服務器上的配置問題了。豈不是我們每次對數據庫讀寫都得加上“SET NAMESUTF8”,以保證數據傳輸的編碼一致?能不能通過配置MySQL來達到那三個變量默認就為我們要想的字符集?手冊上沒說,我在網上也沒找到答案。所以,從服務器配置的角度而言,是沒辦法省略掉那行代碼的.

那mysql_set_character_set又做了什么呢?代碼如下:

  1. //mysql-5.1.30-SRC/libmysql/client.c, line 3166: 
  2.  int STDCALLmysql_set_character_set(MYSQL*mysql, const char *cs_name) 
  3.  { 
  4.    structcharset_info_st *cs; 
  5.    const char *save_csdir= charsets_dir; 
  6.    
  7.    if (mysql->options.charset_dir) 
  8.      charsets_dir= mysql->options.charset_dir; 
  9.    
  10.    if (strlen(cs_name) < MY_CS_NAME_SIZE && 
  11.       (cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY, MYF(0)))) 
  12.    { 
  13.      char buff[MY_CS_NAME_SIZE + 10]; 
  14.      charsets_dir= save_csdir; 
  15.      /* Skip execution of "SET NAMES" for pre-4.1 servers */ 
  16.      if (mysql_get_server_version(mysql) < 40100) 
  17.        return 0; 
  18.      sprintf(buff, "SET NAMES %s", cs_name); 
  19.      if (!mysql_real_query(mysql, buff, strlen(buff))) 
  20.      { 
  21.        mysql->charset= cs; 
  22.      } 
  23.    } 
  24.    //以下省略 

我們可以看到,mysqli_set_charset除了做了”SET NAMES”以外, 還多做了一步,代碼如下:

  1. sprintf(buff, "SET NAMES %s", cs_name); 
  2. if (!mysql_real_query(mysql, buff, strlen(buff))) 
  3.   mysql->charset= cs; 

而對于mysql這個核心結構的成員charset又有什么作用呢?

這就要說說mysql_real_escape_string()了, 這個函數和mysql_escape_string的區別就是, 它會考慮”當前”字符集. 那么這個當前字符集從哪里來呢?

對了, 你猜的沒錯, 就是mysql->charset.

mysql_real_string在判斷寬字符集的字符的時候, 就根據這個成員變量來分別采用不同的策略, 比如如果是utf-8, 那么就會采用libmysql/ctype-utf8.c.代碼如下:

  1. <?php 
  2.      $db = mysql_connect('localhost:3737''root' ,'123456'); 
  3.      mysql_select_db("test"); 
  4.      $a = "x91x5c";//"?"的gbk編碼, 低字節為5c, 也就是ascii中的"" 
  5.    
  6.      var_dump(addslashes($a)); 
  7.      var_dump(mysql_real_escape_string($a$db)); 
  8.      //Vevb.com 
  9.      mysql_query("set names gbk"); 
  10.      var_dump(mysql_real_escape_string($a$db)); 
  11.    
  12.      mysql_set_charset("gbk"); 
  13.      var_dump(mysql_real_escape_string($a$db)); 
  14.  ?>

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 华蓥市| 榕江县| 泸定县| 贺州市| 家居| 阿图什市| 富川| 兴隆县| 松江区| 青浦区| 山阳县| 乌拉特后旗| 库尔勒市| 定州市| 财经| 九龙县| 长汀县| 阜康市| 修水县| 仁怀市| 沙河市| 仙游县| 泌阳县| 平南县| 常德市| 怀化市| 南昌市| 鹤岗市| 会昌县| 集贤县| 巴青县| 醴陵市| 辽中县| 延川县| 临海市| 蓬安县| 万山特区| 维西| 舟曲县| 昭觉县| 阿拉善左旗|