Apache和PHP網頁的編碼問題分析
談談Apache和PHP網頁的編碼。還有一篇關於MySQL字符集的:http://potatows.eeie.cn/?p=39
談到Apache的編碼我們就要涉及到3個東西
http標記語言中的<META http-equiv="content-type" content="text/html; charset=xxx">標簽
PHP中的header("content-type:text/html; charset=xxx");函數
Apache配置文件httpd.conf中的AddDefaultCharset
一、<META http-equiv="content-type" content="text/html; charset=xxx">標簽
按順序來,先說這個<META>標簽,這個標簽有很多功能的,具體請點這裡。
我今天想說只是上面提到的那種形式。解釋一下<META http-equiv="content-type" content="text/html; charset=utf-8">,意思是對這個網頁進行聲明,讓浏覽器對整個頁面的內容采用xxx編碼,xxx可以為GB2312,GBK,UTF-8(和MySQL不同,MySQL是UTF8)等等。因此,大部分頁面可以采用這種方式來告訴浏覽器顯示這個頁面的時候采用什麼編碼,這樣才不會造成編碼錯誤而產生亂碼。但是有的時候我們會發現有了這句還是不行,不管xxx是哪一種,浏覽器采用的始終都是一種編碼,這個情況我後面會談到。
請注意,<meta>是屬於html信息的,僅僅是一個聲明,它起作用表明服務器已經把HTML信息傳到了浏覽器。
二、header("content-type:text/html; charset=xxx");
這個函數header()的作用是把括號裡面的信息發到http標頭。關於此函數具體用法請點擊這裡。
如果括號裡面的內容為文中所說那樣,那作用和<META>標簽基本相同,大家對照第一個看發現字符都差不多的。但是不同的是如果有這段函數,浏覽器就會永遠采用你所要求的xxx編碼,絕對不會不聽話,因此這個函數是很有用的。為什麼會這樣呢?那就得說說HTTPS標頭和HTML信息的差別了:
引用:
https標頭是服務器以HTTP協議傳送HTML信息到浏覽器前所送出的字串。
因為meta標簽是屬於html信息的,所以header()發送的內容先到達浏覽器,通俗點就是header()的優先級高於meta(不知道可不可以這樣講)。加入一個php頁面既有header("content-type:text/html; charset=xxx"),又有<META http-equiv="content-type" content="text/html; charset=xxx">,浏覽器就只認前者http標頭而不認meta了。當然這個函數只能在php頁面內使用。
同樣也留有一個問題,為什麼前者就絕對起作用,而後者有時候就不行呢?這就是接下來要談的Apache的原因了。
三、AddDefaultCharset
Apache根目錄的conf文件夾裡,有整個Apache的配置文檔httpd.conf。具體如何配置apache請點擊這裡([url=thread-2674-1-1.html]windows[/url],[url=thread-1381-1-1.html]linux[/url])。
用文本編輯器打開httpd.conf,第708行(不同版本可能不同)有AddDefaultCharset xxx,xxx為編碼名稱。這行代碼的意思:設置整個服務器內的網頁文件https標頭裡的字符集為你默認的xxx字符集。有這行,就相當於給每個文件都加了一行header("content-type:text/html; charset=xxx")。這下就明白為什麼明明meta設置了是utf-8,可浏覽器始終采用gb2312的原因。
如果網頁裡有header("content-type:text/html; charset=xxx"),就把默認的字符集改為你設置的字符集,所以這個函數永遠有用。如果把AddDefaultCharset xxx前面加個“#”,注釋掉這句,而且頁面裡不含header("content-type…"),那這個時候就輪到meta標簽起作用了。
總結:
來個排序
header("content-type:text/html; charset=xxx")
AddDefaultCharset xxx
<META http-equiv="content-type" content="text/html; charset=xxx">
如果你是web程序員,給你的每個頁面都加個header("content-type:text/html; charset=xxx"),保證它在任何服務器都能正確顯示,可移植性強。
至於那句AddDefaultCharset xxx,要不要注釋就仁者見仁了。反正我是注釋掉了,不過我寫頁子也要寫header(),便於放到不同的服務器上能正常顯示。