前言:
說實話,
涼鞋也覺得 utf8 是好東西……
畢竟同屏顯示中日韓對東亞人的吸引力是不小的……
(當然好處不僅是這點啦……)
不僅是網頁程式……
很多應用程式的內核都開始使用 unicode 編碼……
目的是顯而易見的:支援多語言顯示……
微軟的所有軟體都是 unicode 內核……
所以日文軟體拿到你的中文 xp 上是可以正常顯示的……
而中文 98 就會因為 gb 內核安裝其他語言軟體時造成亂碼……
至于 utf8 ,
可以說是 unicode 的一個分支,
它用三個字節保存一個漢字……
(unicode 用四個字節)
應用軟體都集體投奔 unicode 了……
就不允許我們搞網頁程式的用 utf8?
本文中涼鞋就盡量多方位介紹一下 utf8 編碼下的 php 編程……
至于為什么單獨介紹“中文”……
一來是因為英文這玩意實在不需要考慮 utf8 ……
除非你準備做多語言系統……
(我要發些牢騷:現在的老外寫程式時根本不重視這個問題……)
二來是中日韓等多字節語系在 utf8 編碼下的處理方式其實大同小異……
依葫蘆畫瓢即可……
好……先從數據庫處理部分開始吧……
==========================================
連接數據庫
很多人剛升級到 mysql 4.1 時會發現數據亂掉了……
其實是因為 mysql 從 4.1 開始支援字符集了……
而且默認字符集正是 utf8 ……
(充分證明與國際接軌的重要性…… 嘿嘿……)
而以前我們大多使用 utf8 或是 gbk 編碼……
這樣以來輸出的數據當然是亂碼……
要解決亂碼……
就得讓程序知道該獲取什么編碼的數據……
我們假設你以前的數據庫是 utf8 編碼的……
那么你可以在查詢前添加一句
mysql_query('set character set utf8') or die("query failed : " . mysql_error());
當然,由于 4.1 以上才需要這樣處理,
因此我們可以加上判斷:
$mysqlversion = $db->query_first("select version() as version");
if ($mysqlversion['version'] >= '4.1')
{
mysql_query('set character set utf8') or die("query failed : " . mysql_error());
}
這樣以來不管 mysql 默認編碼是什么都可以正常存取了……
(不論您是存活期,還是存定期,甚至是零存整取都沒有問題鳥……)
但是,人家都國際化鳥……
您還在用 utf8 行么?
如何轉碼呢?
還有……
數據升級時出現亂碼怎么辦?
涼拌!
且聽下回分解……
============================================
數據升級至 4.1
要升級……
就得先導出……
要說老外還真不負責……
以前的導出方式總是弄丟一些中文字符……
比如把“我愛你娘”弄成“我愛你”啦……
(通常是丟失一段數據最末尾的字)
整個兒差了一輩兒……
(用石榴姐的話說就是“這么大逆不道的事實在是太刺激了”……)
為了保護您脆弱的心臟……
也為了維護中國傳統倫理道義……
您可以把數據包含中文字符的字段改為二進制(binary)編碼……
具體方法嘛……
可以運行這個語句:
alter table `表名` convert to character set binary;
這樣,那些字符類型字段,如:
char、varchar 和 text
將轉換為
binary、varbinary 和 blob
然后再導出并導入到 4.1 環境中……
當然,最后一項繁瑣的工作是:
你需要把它們的類型再改回來……
有往 4.1 升級的……
當然也有往下降級的……
怎么降級???
涼鞋去上個廁所……
而您請翻下頁……
=============================================
數據從 4.1 降級
有人發現從4.1導出的 sql 文件無法導入低版本程序……
問題其實很簡單……
而且 mysql 已經為我們想好了一切……
導出時請添加 –compatible 參數……
我們假設您的數據庫是 utf8 編碼的……
而且目標數據庫版本為 4.0 ……
那么命令行下這么寫:
shell>mysqldump --user=username --password=password --compatible=mysql40 --default-character-set=utf8 database > db.sql
這樣導出的 sql 文件就能夠順利導入低版本數據庫了……
數據庫部分算是搞定了……
但 php 編程方面要如何注意呢?
還得勞您翻下頁……
http://www.knowsky.com
=============================================
php 文件編碼
是否所有 php 文件都必須轉成 utf8 編碼呢?
涼鞋告訴您是 no ……
這么說吧……
如果文件中包含需要顯示出來的中文字符……
就應該轉為 utf8 編碼……
舉例子吧:
// 我是涼鞋
echo time();
上面的代碼雖有代碼……
但是由于存在于注釋中……
不會輸出……
所以這個頁面可以不用轉換為 utf8 格式……
再如:
echo "我是涼鞋";
這個明顯有中文字符輸出……
您還是老老實實轉換為 utf8 吧……
當然現在很多程式都采用模板(語言包)技術……
程式(非語言包文件)里是看不到任何供輸出的字符的……
這樣以來我們只需要將語言包文件轉成 utf8 編碼即可……
(語言包的優勢就在這里啊…… 啊哈哈哈哈哈……)
'http://www.knowsky.com
==================================================
utf8 中文截取
由于 utf8 使用三個字節……
所以傳統的 substr 函數就沒轍了……
很多高手都寫了 utf8 中文字符截取函數……
這里送上幾種:
1.先算再取
/**
* author : dummy | zandy
* email : [email protected] | hotmail.com
* create : 200512
* usage : echo join('', string::substring_utf8('漢字', 0, 1));
*/
ini_set('display_errors', 1);
error_reporting(e_all ^ e_notice);
class string {
function substring_utf8($str, $start, $lenth)
{
$len = strlen($str);
$r = array();
$n = 0;
$m = 0;
for($i = 0; $i < $len; $i++) {
$x = substr($str, $i, 1);
$a = base_convert(ord($x), 10, 2);
$a = substr('00000000'.$a, -8);
if ($n < $start){
if (substr($a, 0, 1) == 0) {
}elseif (substr($a, 0, 3) == 110) {
$i += 1;
}elseif (substr($a, 0, 4) == 1110) {
$i += 2;
}
$n++;
}else{
if (substr($a, 0, 1) == 0) {
$r[] = substr($str, $i, 1);
}elseif (substr($a, 0, 3) == 110) {
$r[] = substr($str, $i, 2);
$i += 1;
}elseif (substr($a, 0, 4) == 1110) {
$r[] = substr($str, $i, 3);
$i += 2;
}else{
$r[] = '';
}
if (++$m >= $lenth){
break;
}
}
}
return $r;
} // end substring_utf8
}// end string
echo join('', string::substring_utf8('漢字', 0, 1));
2.先截后取
這種方式涼鞋覺得很巧妙……
用傳統截取函數先截斷……
然后判斷中文單個字符是否被分割開……
如果是……則處理之……
要特別注意的是 substr 函數的第三個參數必須大于 3 ……
至于為什么不用涼鞋解釋了吧?
// a trim function to remove the last character of a utf-8 string
// by following instructions on http://en.wikipedia.org/wiki/utf-8
// dotann
// usage: $str = utf8_trim(substr($str,0,50));
function utf8_trim($str) {
$len = strlen($str);
for ($i=strlen($str)-1; $i>=0; $i-=1){
$hex .= ' '.ord($str[$i]);
$ch = ord($str[$i]);
if (($ch & 128)==0) return(substr($str,0,$i));
if (($ch & 192)==192) return(substr($str,0,$i));
}
return($str.$hex);
}
$str = '漢字';
echo utf8_trim(substr($str,0,3));
3.還有其它方法,
比如 007pig 為我們 vbulletin 中文版里所寫的函數……
短小精悍……
源碼不便放出……
對不住鳥……
新聞熱點
疑難解答