国产探花免费观看_亚洲丰满少妇自慰呻吟_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.  ?>

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 司法| 扎赉特旗| 扎兰屯市| 砀山县| 盐山县| 涟水县| 曲水县| 舒兰市| 玉屏| 海伦市| 莲花县| 班戈县| 德令哈市| 贵港市| 平和县| 江城| 瑞安市| 洛宁县| 和静县| 调兵山市| 光泽县| 沧州市| 长丰县| 措美县| 平顶山市| 灵寿县| 金阳县| 浦县| 临海市| 孙吴县| 青田县| 丹阳市| 察隅县| 和林格尔县| 阳朔县| 荔浦县| 抚宁县| 渑池县| 澄江县| 石狮市| 乐山市|