日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

转乱码UTF8和UTF-8网页编码

發布時間:2023/11/27 生活经验 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 转乱码UTF8和UTF-8网页编码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://www.lovelucy.info/utf8-vs-utf-8.html#more-794

一、遇到的問題

曾經被字符集間復雜的轉換搞怕了,正好新項目要求國際化,需要能夠顯示多種語言,于是一開始就規定統統使用 UTF-8 編碼。

  1. 所有代碼文件使用 UTF-8 編碼存盤
  2. MySQL數據庫所有表,所有字段設置 Collation (中文翻譯為“整理”?)屬性為 “utf8_general_ci”
  3. 所有頁面輸出
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">

即便是這樣,PHP 從數據庫中讀取內容,顯示到網頁上,還是出現了亂碼,英文沒問題,中文統統都是?問號。這樣也行?艱苦卓絕的 debug 開始了……

二、調查原因

MySQL 的字符集以繁多而著名,而其默認又是 latin1 的瑞典語編碼,數據導入導出的時候一不留神就亂碼了。

參考以上鏈接的官方文檔,總結之:MySQL 對于字符集的支持細化到四個層次:

  1. server 服務器級
  2. database 數據庫級
  3. table 表級
  4. connection 連接級

確保每一個級別都是使用的 UTF-8 編碼。檢查了一下,貌似我沒有設置 connection 連接級。前 三種字符集級別只是規定了數據存儲在 MySQL 中的編碼格式,客戶端讀出數據后完全可以按照自己的意愿來解讀數據。最后的 connection 連接級就是規定了客戶端以什么編碼來解析讀取到的數據。也就是說,不論是 php 代碼還是 DB 管理軟件,在從 MySQL 讀取數據之前都需要設定自己作為客戶端的編碼格式。

好吧,那么,在任何查詢執行之前,先執行一句 set names utf-8。(使用框架進行開發的話,大多數框架應該會自動完成這一步,程序員一般只需要改配置文件)

$conn = mysql_connect($db_host, $db_user, $db_password);
if(!$conn)
die("Could not connect to mysql.");
mysql_select_db($db_name);
mysql_query("set names 'utf-8'");

刷新頁面,仍舊亂碼。

三、解決

只好再繼續調查。¥#$…&%=^*&+%-#!@_@ 苦逼地一天就這樣過去了……

咦,等等,官方文檔里寫的是 set names utf8 哦,和 set names utf-8 有啥區別么?趕緊試一下。

刷新頁面,我擦,正常了。

搜了一下,發現被坑的人還真不少。UTF-8應該是標準的寫法,在大多數場合都是有中間那個橫杠的,只是MySQL這里偏偏就非主流去掉了橫杠使用UTF8。

遇到同樣問題,而本文未能幫你解決的,這篇亂碼總結可能會幫到你。

?

//以下是討論內容

今天看到大家在討論,發現這是個很嚴重而又容易疏忽的問題,我以前也一直是用set names,遂記錄下來,也提醒自己一把。

應該使用 mysql_ set_ charset(); 不要使用sql query來設置,有風險。

1.set names與mysql_set_charset有什么區別?

一般情況下, 使用”SET NAMES”就足夠了, 也是可以保證正確的. 那么為什么手冊又要說推薦使用 mysqli_set_charset(PHP>=5.0.5)呢。手冊里面也沒有明確說明。我們可以看下php擴展的源代碼:

//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;
}
可以看到php的mysql擴展是直接調用了mysql的mysql_set_character_set函數,接下來看看mysql的代碼

//mysql-5.1.30-SRC/libmysql/client.c, line 3166:
int STDCALL mysql_set_character_set(MYSQL *mysql, const char *cs_name)
{
struct charset_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) charset= cs;
}
}
//以下省略
可以看到,除了調用real_query設置set names,還設置了mysql的charset變量。

2.這樣有什么影響?

mysql_real_escape_string會受到影響,它與mysql_escape_string的區別就 是, 它會考慮”當前”字符集。如果僅僅使用set names,mysql_real_escape_string可能會失效。

例子:

$mysqli = new mysqli(“localhost”, “user”, “pass”, “test”, 3306);

/* check connection */
if (mysqli_connect_errno()) {
printf(“Connect failed: %s\n”, mysqli_connect_error());
exit();
}

$mysqli->query(‘SET NAMES gbk’); //使用set names設置字符集
$city = chr(0xbf).chr(0x5c); //0xbf5c是個有效的gbk字符,模擬用戶輸入
$city = $mysqli->real_escape_string ($city);//使用real_escape進行過濾

/* this query will fail, cause we didn’t escape $city */
if (!$mysqli->query(“INSERT into myCity(name) VALUES (‘$city’)”)) {
print “INSERT into myCity (name) VALUES (‘$city’)\n”;
printf(“Error: %s\n”, $mysqli->error);
}

var_dump($city);

var_dump($mysqli->client_encoding());

$mysqli->close();
3.解決方案

mysqli_set_charset函數對PHP和Mysql有版本要求,必須當mysql版本大于5,PHP版本大于5.0.5時,此函數才有 效。至于另一個mysql_set_charset函數,則更要求PHP版本大于5.2.3時才能有效。對于mysql4.1以上版本,使用”SET character_set_client=binary;”
推薦使用mysql_set_charset設置字符集的方案,只有在環境不允許的情況下,我們才推薦使用第二種binary編碼的方案。但是無論在什么情況下,都禁止使用”SET NAMES”來作為設置字符集的操作。

轉載于:https://www.cnblogs.com/xiaohong/archive/2012/03/13/2393327.html

總結

以上是生活随笔為你收集整理的转乱码UTF8和UTF-8网页编码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。