《現代 PHP》學習筆記(十七):多位元組字串

前言

本文為《現代 PHP》一書的學習筆記。

環境

  • Windows 10
  • Wnmp 3.1.0

多位元組字串

PHP 假設每個字串中的字元都是 8 位元字元,也就是占用記憶體中的一個位元組,不過非英語系字元很有可能是多位元組字元,必須妥善處理。

多位元組字元指的是不存在於 128 個傳統 ASCII 字元組之中的字元,如果用 PHP 原生的字串處理函式處理包含了多位元組字元的 Unicode 字串,將會得到非預期的錯誤結果。

可以安裝 PHP 擴充 mbstring 來避免多位組字串產生的錯誤,比方它以多位元組版本的 mb_strlen() 函式取代了原生的 strlen() 函式。

字元編碼

所有現代的網頁瀏覽器都支援 UTF-8 字元編碼,字元編碼是把 Unicode 資料包裝成一個格式的方法,讓資料可以被儲存在記憶體中或是在伺服器和客戶端之間的線路傳送。

Unicode 與 UTF-8 的關係:

  • Unicode 是「字符集」,為每一個「字符」分配一个唯一的碼位。
  • UTF-8 是「字元編碼」,是 Unicode 的一種變長度的編碼表達方式。
位元組序列 位元組 1 位元組 2 位元組 3 位元組 4
1 0xxxxxxx - - -
2 110xxxxx 10xxxxxx - -
3 1110xxxx 10xxxxxx 10xxxxxx -
4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

UTF-8 根據不同的符號而變化位元組長度,編碼規則如下:

  • 對於單位元組的符號,位元組的第一位設為 0,後面 7 位為這個符號的 Unicode 碼。因此對於英語字母,UTF-8 編碼和 ASCII 碼是相同的。
  • 對於 n 位元組的符號,第一個位元組的前 n 位都設為 1,第 n+1 位設為 0,後面位元組的前兩位一律設為 10。剩下的全部為這個符號的 Unicode 碼。

UTF-8 的編碼中的第一個位元組與 ASCII 相容,範例如下。

字符 ASCII Unicode (hex) UTF-8 (hex)
A 01000001 00000000 01000001 (41) 01000001 (41)
- 01001110 00101101 (4E2D) 11100100 10111000 10101101 (E4B8AD)

輸出 UTF-8 資料

當要處理多位元組字串時,必須告訴 PHP 正在處理 UTF-8 字元編碼,只要在 php.ini檔中加入以下這行即可。

1
default_charset = "UTH-8";

或者在 PHP 檔中使用 header() 函式特別指明。

1
header('Content-Type: application/json;charset=utf-8');
  • header() 函式前,不能有任何輸出。

另外,最好在 HTML 文件標頭中加入 meta 標籤。

1
<meta charset="UTF-8" />

參考資料

  • Josh Lockhart(2015)。現代 PHP。台北市:碁峯資訊。