字元集
作者:360weboy
新浪微博:http://weibo.com/360weboy
博文連結: http://www.360weboy.com/php/fundament/charset.html
上個星期在為一個電子商務網站進行資料轉移到新系統中的時候,發現一些產品描述字元老是輸出亂碼,確定是字元集的問題以後,對字元集再次進行了一次調研,確定了影響頁面字元集的方式主要下面幾種方式:
1. 檔案的編碼方式
2. Apache2的預設字元集設定
3. PHP.ini中的預設字元集的設定
4. PHP指令碼中手動輸出header(‘Content-type:text/html;charset=xxx’);
5. html頁面中加入
我對以上五種方式都進行了一一測試,並且確定了5種方式對於瀏覽器字元集選擇的優先順序。首先我建立了一個以utf8編碼的test.php檔案,內容如下:
我使用chrome訪問test.php, 因為我的chrome瀏覽器的預設字元集不是utf8,應該是gb2312或者gbk,所以我在瀏覽器中看到了如下亂碼:
header與meta的優先順序比較
接下來,先來測試以上的4,5兩種方式。我向html頁面中分別加入了,內容顯示正常。
去掉header中的meta標籤,加入header(‘Content-type:text/html;charset=utf8′);內容顯示正常。那麼,meta標籤和header的方式,那個優先順序高呢,我在頁面裡同時設定了這兩項,header設定為gb2312, meta設定為utf8:
結果內容顯示不正常,說明header的優先順序高。瀏覽器先採用http頭部中的字元集設定,然後是html頁面中meta標籤設定的字元集。
php.ini中設定預設字元集以後的影響
接下來,我們來看下在php.ini中設定預設字元集以後的情形。為了測試下優先順序,我們先將頁面中的header以及meta設定的字元集都改為gb2312,那麼這樣內容肯定顯示為亂碼。然後,我們開啟php.ini檔案,找到如下設定,去掉前面的引號,設定字元集為utf8:
設定好以後,記得要重啟下apache2伺服器,結果顯示如下:
我們看到,在php.ini設定預設字元集為utf8以後,它被加入到了回應標頭Content-type末尾,從而覆蓋了在php指令碼中通過header函數輸出的gb2312的字元集,瀏覽器根據該頭部中的資訊,認為內容是utf8的字元集,最後內容現實正常。由此可見,php.ini中字元集設定的優先順序高於header函數以及meta標籤。
apache2中設定預設字元集
最後,我們來設定下apache2中的預設字元集來測試下。這次將header,meta,php.ini中的字元集都設定為gb2312,然後在apache2設定預設字元集為utf8:
重啟apache2伺服器,內容顯示如下:
由此可見,apache2中的字元集的設定沒有影響到http響應中的Content-Type頭部,所以瀏覽器認為應該用gb2312來解碼,導致出現亂碼。那麼,如果去掉php.ini中的字元集的設定以後內,頁面是否會顯示正常。經過測試,顯示如下:
看來,apache2中的字元集的優先順序同樣小於header函數的字元集設定。我們繼續去掉header的設定看下:
以上證明,apache2中的字元集設定的優先順序高於meta標籤的字元集設定。charset=utf8加入到了http頭部中。
綜合上述實驗,得出字元集設定優先權順序: php.ini預設字元集設定 > header函數字元集設定 > apache2預設字元集設定 > meta標籤字元集設定
回複討論(解決方案)
這個結果不太認同
測試有局限性
1.只使用了單一瀏覽器測試
2.只使用了一種語系測試
3.只使用了單一檔案編碼測試
最大的問題是所有測試都是正向測試,就是符合預期就認為該項是正確的,這是邏輯大忌
為什麼實驗過程沒有問題,但得出的結論是錯誤的呢?
經測試:
default_charset 的優先順序小於 header 函數字元集設定
優先順序的順序根據我和朋友的測試是對的,請自己核對。
snmr_com
請指教,你知道測試問題所在,那麼能不能說下,這個過程應該怎麼測試才算標準。。多謝!
http://www.w3help.org/zh-cn/causes/HR9001
可以參考這邊文章,但這文章也比較舊了
你用的是歸納法推導,完全歸納法的基礎就是滿足所有的可能性得出一致(唯一)結論
並且,因為你的這個命題各種可能性並非符合“良序”特性,不能用數學歸納法那樣的兩步求證
所以,你要做測試就要遍曆所有的可能性,如果沒有遍曆所有可能性,那麼結論就只能增加限定條件
例如
只涉及一種瀏覽器,結論就只能縮小到該瀏覽器
原文檔只使用了一種編碼,那結論也只能適用於這種編碼
基本上增加了兩三個限定條件,結論就沒有太大的實用意義,因為適用範圍變得很小了
所以還是要做更多的測試以支援你的結論才行
你命題涉及的條件有:瀏覽器、各優先順序的編碼指定、語系(特別是較難自動識別的不同語系,如同是雙位元組中日韓編碼)、文檔編碼,做一個排列組合,可能性就相當多了……如果能全部測試一遍,還是相當佩服你的,呵呵
專業的理論指導,兄弟佩服。。。有時間再完整的走一遍。。多謝回複
優先順序的順序根據我和朋友的測試是對的,請自己核對。 php.ini
運行介面
你測試的結果並不代表我測試的結果
何況 header 就該能改變相關預設值,否則還要他幹什嗎?