闡述
最近幾天與公司的PHP開發人員測試即將上線的WEB站點(致難忘的青春歲月:http://hd.gfan.com),在內網測試環境沒有任何問題,但在線上測試時,發現通過PHP的GD函數 p_w_picpathfttext()引用FreeType字體將文本信息寫入圖像時,出現中文亂碼;對此問題,我們在整個排查過程中,總結了三個能引起中文亂碼的原因,如下:
1、Linux系統字符集是否支持中文?
root@exiuxiu-web1:~#locale LANG=en_US.UTF-8 LANGUAGE=en_US.UTF-8 LC_CTYPE="en_US.UTF-8" root@exiuxiu-web1:~#echo $LANG en_US.UTF-8
##提示
在Linux系統中,支持中文的字符集有Unicode、GB1232、UTF-8、GBK、GB18030,通過命令locale,echo $LANG可以查詢系統默認使用的字符集是否支持中文,如果你的系統默認字符集不支持中文,請瀏覽擴展閱讀,瞭解相關中文字符集的信息,在根據你架構的實際需求選擇字符集。
擴展閱讀:
http://zh.wikipedia.org/wiki/GB18030
http://zh.wikipedia.org/wiki/GB2312
http://zh.wikipedia.org/wiki/UTF8
http://zh.wikipedia.org/wiki/GBK
http://zh.wikipedia.org/wiki/Unicode
2、Linux是否支持Windows字體(黑體、宋體)?
在測試之前,整個WEB站點的PHP代碼是通過SVN更新至線上的服務器,其中有一點需要說明的是,在使用PHP的GD函數p_w_picpathfttext()將文本寫入圖片時,引用了Windows端的字體庫(simhei.ttf黑體、simsun.ttc宋體、simfang.ttf仿宋),所以我們懷疑是否因爲Linux系統不支持Windows系統的字體而引起的,爲此在Linux系統下添加了Windows系統的字體庫,不幸的是問題並沒有解決;引用Linux字體庫也是如此;
##擴展閱讀:
如何向Linux添加Windows字體
http://www.cnblogs.com/hiflex/archive/2012/08/12/2634532.htmlhttp://os.51cto.com/art/201402/429516.htm
3、是否由PHP編譯參數引發中文亂碼問題?
通過phpinfo()函數輸出測試環境與線上環境的PHP編譯參數,相互對比發現線上環境比測試環境多了個--enable-gd-jis-conv參數,對此,我們在PHP官方文檔中查的如下信息:
*雖然 p_w_picpathttftext()文檔標明只接受UTF-8編碼,但如果PHP編譯時啓用–enable-gd-jis-conv選項的話,那麼非ASCII字符(例如漢字、拼音、希臘文和箭頭) 會被當成EUC-JP編碼(phpinfo中美其名曰“支持JIS編碼的字體”), 從而導致亂碼(由於西文字體沒有假名或漢字,一般表現爲全部是方框)。
Although p_w_picpathttftext()documentation indicates it only accepts UTF-8 encoding, but if–enable-gd-jis-conv is specified when compiling PHP, then non-ASCII characters(like Chinese, accented characters, Greek and arrows) will be (mis-)treated asEUC-JP encoding (referred to as “JIS-mapped Japanese Font Support” in phpinfo)leading to mojibake (this usually shows up as hollow rectangles, as most fontsfor western text lacks glyphs for kanji or kana).
3、1 啓用PHP參數–enable-gd-jis-conv,測試結果如下:
Firefox瀏覽器附加web調試工具firebug
#提示:從圖中輸出的結果,我們可以得知服務器端是支持中文字符集,問題發生在GD函數p_w_picpathfttext()將文本信息寫入圖片時,發生了亂碼的情況,附加測試圖片如下:
3、2 禁用PHP參數–enable-gd-jis-conv,測試結果如下:
我想說,調試bug是一個非常細心,講究團隊協作的事情,首先,我們先不管問題是不是由開發人員、運維人員造成的,但是你需要明白的是兩個部門它是一個團隊,彼此間需要相互協作,爭取在最短的時間內解決問題,因爲在沒有得到最終的結論之前,我們都無法確定問題是誰導致的,該由誰去負責,希望這篇文檔能幫助到大家;
擴展閱讀: