程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 簡單談談php中的unicode和utf8編碼

簡單談談php中的unicode和utf8編碼

編輯:關於PHP編程

     重新認識unicode和utf8編碼

    直到今天,准確的說是剛才,我才知道UTF-8編碼和Unicode編碼是不一樣的,是有區別的囧
    他們之間是有一定的聯系的,看看他們的區別:
    UTF-8的長度是不一定的,有可能是1、2、3字節
    Unicode長度一定,2個字節(USC-2)
    UTF-8可以和Unicode互相轉換

    unicode和utf8的關系

    Unicode(16進制)

    UTF-8(二進制)

    0000 - 007F 0xxxxxxx
    0080 - 07FF 110xxxxx 10xxxxxx
    0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx

    上面的表格有2個意思,第一個顯而易見就是說Unicode和UTF-8字符范圍的對應,還有一個可以看出Unicode怎麼和UTF-8互相轉換:

    先說UTF-8到Unicode的轉換

    UTF-8編碼的二進制和上面的3種格式進行匹配,匹配到之後去掉固定位(表格中的非x位置),然後從右到左每8位一組,不夠8位左邊不領,湊夠2個字節16 bits,這16 bits所表示的就是UTF-8對應的Unicode編碼,看看下面幾個例子:

    簡單談談php中的unicode和utf8編碼 三聯

    上面圖片中的文字編碼格式為UTF-8,可以用WinHex看到其16進制表示

     代碼如下:


    字符 => UTF-8 => UTF-8二進制=> 去掉固定位置湊夠16位的二進制 => 16進制

     

    漢 => E6B189 => 11100110 10110001 10001001 => 01101100 01001001 => 6C49
    字 => E5AD97 => 11100101 10101101 10010111 => 01011011 01010111 => 5B57

    #下面是在chrome命令行下面運行的結果
    'u6C49'
    "漢"
    'u5B57'
    "字"

    #到這裡的話,從UTF-8轉換到Unicode已經是一件非常容易的事了,看看轉換的偽代碼
    讀取一個字節,11100110
    判斷該UTF-8字符的格式,屬於第三種,3個字節
    繼續讀取2個字節得到 11100101 10101101 10010111
    按照格式去掉固定位 1011011 01010111
    不夠16位,左邊補零 01011011 01010111 => 5B57

     

    再看看從Unicode到UTF-8的轉換

     

    復制代碼 代碼如下:
    5B57
    獲取5B57所在的Unicode范圍,0800 <= 5B57 <= FFFF,得知5B57的UTF-8有三個字節,形式為1110xxxx 10xxxxxx 10xxxxxx
    獲取5B57的二進制編碼 101101101010111
    用上一步驟的二進制編碼從右至左拼接UTF-8編碼 11100101 10101101 10010111

     

    說說問題

    再說說今天這個問題的起因,從前端輸入很多單詞,UTF-8格式每個詞最多30個字節,因此會在前端和後台分別做驗證,javascript用的是Unicode編碼,後端程序用的是UTF-8編碼,現在的解決辦法是這樣

    前端

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 function utf8_bytes(str) { var len = 0, unicode; for(var i = 0; i < str.length; i++) { unicode = str.charCodeAt(i); if(unicode < 0x0080) { ++len; } else if(unicode < 0x0800) { len += 2; } else if(unicode <= 0xFFFF) { len += 3; }else { throw "characters must be USC-2!!" } } return len; }   #例子 utf8_bytes('asdasdas') 8 utf8_bytes('yrt燕睿濤') 12

    後台

    1 2 3 4 #對於GBK字符串 $len = ceil(strlen(bin2hex(iconv('GBK', 'UTF-8', $word)))/2); #對於UTF8字符串 $len = ceil(strlen(bin2hex($word))/2);

    以上所述就是本文的全部內容了,希望大家能夠喜歡。

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved