2015-02-03

Unicode及字元集必備知識、亂碼解決

http://tinyurl.com/y7vw4t

如果你對ASCII、ANSI、unicode、UTF-8、UTF-16、UCS-2...
這些Code編碼還搞不清楚的話,上面這篇文章有蠻清楚的說明。

之前也是被這些編碼問題搞得很頭大,後來發現一些小技巧就可以解決:
html可使用meta改變瀏覽器的預設編碼(但不是每次都有效,視瀏覽器而定):




這麼做有個缺點,因為web server跟本就不知道你的網頁編碼,meta是給瀏覽器看的,假設你寫了個utf-8編碼存檔的網頁,meta也設utf-8,但apache的header搞不好是設定成big5或iso-8859-1,所以你可能會看到亂碼。可以把php.ini中的default_charset 幹掉或是直接設成你要的編碼(但會影響全部),再把apache的httpd.conf中的AddDefaultCharset off掉,不要讓apache決定預設編碼,接下來就由你自由決定程式編碼了,

php寫mail程式要記得改變它的mail header:
header('Content-Type: text/plain; charset="UTF-8"');

php script也是改變header:
header("Content-Type: text/html; charset=utf-8");

或直接改變php環境的default charset:
ini_set('default_charset','utf-8')

當然你千萬不要白目到用big5存程式然後要顯示utf-8,那樣的話就需要做字符轉換了!像iconv就可以幫忙這樣的事,
shell:iconv -c -f CP950 -t UTF-8 或 iconv -c -f BIG5 -t UTF-8
php: iconv('BIG5', 'UTF-8', $string) 或 iconv('CP950', 'UTF-8', $string);
這樣就可以把該死又腦殘的BIG5轉成UTF-8。(但有些沒法轉的字會被吃掉!)
有興趣做簡繁互換網頁的可以參考下面這篇更簡單的方法:
http://blog.markplace.net/marks_place/10/2006/10/27/150

//////////不過程式對SQL的連線又是另一回事了,比上述問題還煩。
常常會看到一種情形是資料庫用latin1存big5或utf-8,平常用的時候都看來好好的(反向處理咩),但實際的collation(連線校對)是錯的!!而現在新版的phpmyadmin跟mysql,預設都是用utf-8了,如果有哪天要做資料庫的備份與回存,實在會搞死人。

一般用latin1存成big5,而想要轉存成utf-8的話都會這樣解決:
mysqldump -u user -p -default-character-set=latin1 database > output.sql
piconv -f big5 -t utf8 output.sql > utf8.sql

如果原先是用latin1存成utf-8的話,要先轉成big-5,再轉utf-8,才不會出問題。
mysqldump -u 帳號 -p -default-character-set=latin1 database > output.sql
piconv -f utf8 -t big5 output.sql > big5.sql
piconv -f big5 -t utf8 big5.sql > utf8.sql

如果原先是用latin1存成utf-8的話,要先轉成big-5,再轉utf-8,才不會出問題。
mysqldump -u 帳號 -p -default-character-set=latin1 database > output.sql
piconv -f utf8 -t big5 output.sql > big5.sql
piconv -f big5 -t utf8 big5.sql > utf8.sql

再修改一下dump出來的資料庫,前面加上:
SET NAMES utf8;
SET CHARACTER_SET_CLIENT=utf8;SET CHARACTER_SET_RESULTS=utf8;
資料庫裡面要是有「許功蓋」這些字,就砍掉多出來的"\"
而且每個資料表的前面的 TYPE=MyISAM;
都改成 ENGINE=MyISAM DEFAULT CHARSET=utf8;

然後建個空的資料庫準備import:
//SET GLOBAL/SESSION character_set_XXX=utf8 //其實不需要用到全域...
CREATE DATABASE `mydatabase` DEFAULT CHARACTER SET utf8
COLLATE utf8_general_ci;
http://dev.mysql.com/doc/refman/5.0/en/charset-syntax.html

然後就是import了:
mysql -u user -p database < utf8.sql

/////////////////////寫php的人注意

MySQL在my.cnf設定:
[client]
default-character-set=utf8
[mysqld]
default-character-set=utf8
default-collation=utf8_general_ci

寫php時,請自行在連線時先下指令:
mysql_query("SET NAMES 'utf8'");
mysql_query("SET CHARACTER_SET_CLIENT=utf8");
mysql_query("SET CHARACTER_SET_RESULTS=utf8");

再檢查語系是否正確:
show variables like “%character%”;

不過要注意一點,如果你"跟本"不想改變原來的編碼方式,只想著能用就好,
(譬如很多人都會犯的錯誤,用latin1存big5或utf-8),那就用這個:
mysql_query("SET NAMES 'latin1'");

只是這樣子以一個寫程式的人來說,「是很不好的習慣」。

話說回來,台南縣網似乎還是很喜歡用big5來發展程式,像xoops,但青菜蘿蔔各有所好,能說什麼呢?I just say "it sucks"!

RoR亂碼問題處理:
http://www.ruby.oss.tw/html/modules/newbb/viewtopic.php?topic_id=335&forum=5
http://ruphus.com/blog/2005/06/23/getting-unicode-mysql-and-rails-to-cooperate/

沒有留言:

張貼留言