今天在遷移服務器的時候遇到一個很詭異的問題,原來一切正常的程序在新的服務器上中文亂碼。
一段 ruby 寫的 cgi script 通過 DBI 訪問 oracle 數(shù)據(jù)庫, 將查詢得到的記錄輸出到頁面。數(shù)據(jù)庫編碼是 gbk, 需要通過 Iconv.conv('utf-8', 'gbk', str) 將字符串轉(zhuǎn)換成 utf-8 輸出。oracle 相關(guān)的環(huán)境變量已經(jīng)設置好。
export LANG=zh_CN.UTF-8
export NLS_LANG=American_America.zhs16cgb231280
export ORACLE_HOME=/home/oracle/oracle/product/10.2.0/client_1
export LD_LIBRARY_PATH=/home/oracle/oracle/product/10.2.0/client_1/lib:$LD_LIBRARY_PATH
在 shell 里執(zhí)行該 cgi script 中文能夠正常顯示,但是通過 apache (非root, oracle用戶)執(zhí)行卻出現(xiàn)亂碼,而且在 apache 下中文都變成了問號。
初步判斷是數(shù)據(jù)庫中的字符在目標字符集下沒有對應的代碼,通常情況就是 iso-8859-1, 那么估計是設置的 oracle 客戶端字符集環(huán)境變量沒有被帶到 apache 執(zhí)行環(huán)境中。在網(wǎng)上 google 到如下:
see http://lamp.linux.gov.cn/Apache/ApacheMenu/mod/mod_env.html#passenv
PassEnv 指令
說明
傳送shell中的環(huán)境變量語法
PassEnv env-variable [env-variable] ...
作用域
server config, virtual host, directory, .htaccess覆蓋項
FileInfo狀態(tài)
基本(B)模塊
mod_env從調(diào)用
httpd
進程所在的shell中,指定一個或者更多個環(huán)境變量,傳送到CGI腳本和SSI頁面。例如:示例
PassEnv LD_LIBRARY_PATH
SetEnv 指令
說明
設置環(huán)境變量語法
SetEnv env-variable value
作用域
server config, virtual host, directory, .htaccess覆蓋項
FileInfo狀態(tài)
基本(B)模塊
mod_env設置一個環(huán)境變量,該變量將會傳送到CGI腳本和SSI頁面。例如:
示例
SetEnv SPECIAL_PATH /foo/bin
這樣在 $APACHE_HOME/conf/httpd.conf 中加入
PassEnv ORACLE_HOME
PassEnv LD_LIBRARY_PATH
PassEnv LANG
PassEnv NLS_LANG
或
SetEnv LANG zh_CN.UTF-8
SetEnv NLS_LANG American_America.zhs16cgb231280
SetEnv ORACLE_HOME /home/oracle/oracle/product/10.2.0/client_1
SetEnv LD_LIBRARY_PATH /home/oracle/oracle/product/10.2.0/client_1/lib:$LD_LIBRARY_PATH
問題都得到了解決