2016年7月6日 星期三

PHP 教學 - 常見亂碼問題

PHP亂碼問題,UTF-8亂碼常見問題小結

    於 HTML head 指定此頁編碼為 UTF-8

        <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        </head>

    PHP 送 Header 告訴瀏覽器這頁是 UTF-8 編碼

        <?php
        header("Content-Type:text/html; charset=utf-8");
        ?>

    設定 Apache 送出頁面預設語系 UTF-8 (比較不建議用此方法)

        addDefaultCharset UTF-8

        # 不過建議這行要包在 Directory 或 VirtualHost 內, 才不會影響到其它網頁.
        <Directory "/var/*/blog">
        addDefaultCharset UTF-8
        </Directory>
        
        <VirtualHost *>
        addDefaultCharset UTF-8
        </VirtualHost>

若PHP程式在遇到繁體中文顯示網頁時,出現亂碼的解決方法:
可以依照下列步驟下去逐一問題排解,

1.檢查php.ini文件裡面的設定
  php.ini路徑:C:\Windows\php.ini

  搜尋到default_charset之後,將文件內容改為
  default_charset="utf-8"
  並將前面的分號";"刪除
  若使用big5則將utf-8改為big5

2.檢查meta標籤
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  若使用big5則將utf-8改為big5

3.檢查my.ini文件裡面的設定
  my.ini路徑:在MySql安裝路徑下即可找到

  搜尋到default-character-set之後,將文件內容改為
  default-character-set = utf8
  若使用big5則將uft-8改為big5

4.若是因為MySql裡面的繁體中文導致亂碼,可直接在程式碼指定語系
  詳細內容可參考此篇PHP 連結MySQL資料庫語法以及從程式碼解決中文亂碼的問題

5.若是html檔案,且已經設定meta標籤內的charset,還是無法解決者
  將html檔案以記事本開啟,
  開啟之後,另存新檔,在最下面編碼的地方該改為 UTF-8



一.HTML頁面轉UTF-8編碼問題
1.在head後,title前加入一行:

<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
順序不能錯,一定要在

顯示的標題有可能是亂碼!

2.html檔編碼問題:

點擊編輯器的功能表:“檔”->“另存為”,可以看到當前檔的編碼,確保檔編碼為:UTF-8,
如果是ANSI,需要將編碼改成:UTF-8。
3.HTML文件頭BOM問題:
將檔從其他的編碼轉換成UTF-8編碼時,有時候會在檔的最開始加上一個BOM標籤,
在個BOM標籤可能會導致流覽器在顯示中文的時候出現亂碼。
刪除這個BOM標籤的方法:
1.可以用Dreamweaver打開檔,並重新保存,即可以去除BOM標籤!
2.可以用EditPlus打開檔,並在功能表“首選項”->“檔”->"UTF-8標識",設置為:“總是刪除簽名”,
然後保存檔,即可以去除BOM標籤!
4.WEB伺服器UTF-8編碼問題:
如果你按以上所列的步驟做了,還是有中文亂碼問題,
請檢查你的所使用的WEB伺服器的編碼問題
如果你使用的是Apache,請將設定檔裡的:charset 設成:utf-8(這裡僅列出方法,具體格式請參考apache的設定檔)
如果你使用的是Nginx,請將nginx.conf裡的:charset 設成 utf-8,
具體找到 "charset gb2312;"或者類似的語句,改成:“charset utf-8;”。
二.PHP頁面轉UTF-8編碼問題
1.在代碼開始出加入一行:
header("Content-Type: text/html;charset=utf-8");

2.PHP檔編碼問題

點擊編輯器的功能表:“檔”->“另存為”,可以看到當前檔的編碼,確保檔編碼為:UTF-8,
如果是ANSI,需要將編碼改成:UTF-8。
3.PHP文件頭BOM問題:
PHP檔一定不可以有BOM標籤
否則,會出現session不能使用的情況,並有類似的提示:
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent
這是因為,在執行session_start() 的時候,整個頁面不能有輸出,但是當由於前PHP頁面存在BOM標籤,
PHP把這個BOM標籤當成是輸出了,所以就出錯了!
所以PHP頁面一定要刪除BOM標籤
刪除這個BOM標籤的方法:
1.可以用Dreamweaver打開檔,並重新保存,即可以去除BOM標籤!
2.可以用EditPlus打開檔,並在功能表“首選項”->“檔”->"UTF-8標識",設置為:“總是刪除簽名”,
然後保存檔,即可以去除BOM標籤!
4.PHP以附件形式保存檔的時候,UTF-8編碼問題:
PHP以附件形式保存檔,檔案名必須是GB2312編碼,
否則,如果檔案名中有中文的話,將是顯示亂碼:
如果你的PHP本身是UTF-8編碼格式的檔,
需要將檔案名變數由UTF-8轉成GB2312:
iconv("UTF-8", "GB2312", "$filename");

5.截斷顯示文章標題時,出現亂碼或者“?”問號的問題:
一般文章標題很長的時候,會顯示一部分標題,會對文章標題進行截斷,
由於一個UTF-8編碼格式的中文字元會佔用3個字元寬度,
截取標題的時候,有時會只截取到一個中文字元的1個字元或2字元寬度,
沒截取完整,將出現亂碼或“?”問號的情況,
用下面的函數截取標題,就不會有問題:

複製代碼代碼如下:


function get_brief_str($str, $max_length)
{
echo strlen($str) ."<br>";
if(strlen($str) > $max_length)
{
$check_num = 0;
for($i=0; $i < $max_length; $i++)
{
if (ord($str[$i]) > 128)
$check_num++;
}

if($check_num % 3 == 0)
$str = substr($str, 0, $max_length)."...";
else if($check_num % 3 == 1)
$str = substr($str, 0, $max_length + 2)."...";
else if($check_num % 3 == 2)
$str = substr($str, 0, $max_length + 1)."...";
}
return $str;
}


三.MYSQL資料庫使用UTF-8編碼的問題

1.用phpmyadmin創建資料庫和資料表
創建資料庫的時候,請將“整理”設置為:“utf8_general_ci”
或執行語句:

CREATE DATABASE `dbname` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
創建資料表的時候:如果是該欄位是存放中文的話,則需要將“整理”設置為:“utf8_general_ci”,

如果該欄位是存放英文或數位的話,預設就可以了。

相應的SQL語句,例如:

複製代碼代碼如下:


CREATE TABLE `test` (
`id` INT NOT NULL ,
`name` VARCHAR( 10 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
PRIMARY KEY ( `id` )
) ENGINE = MYISAM ;


2.用PHP讀寫資料庫

在連接資料庫之後:

[hide]$connection = mysql_connect($host_name, $host_user, $host_pass);

加入兩行:

複製代碼代碼如下:


mysql_query("set character set 'utf8'");//讀庫
mysql_query("set names 'utf8'");//寫庫


就可以正常的讀寫MYSQL資料庫了。

四.JS相關的UTF-8編碼問題
1.JS讀Cookie的中文亂碼問題

PHP寫cookie的時候需要將中文字元進行escape編碼,
否則JS讀到cookie中的中文字元將是亂碼。
但php本身沒有escape函數,我們新寫一個escape函數:

複製代碼代碼如下:


function escape($str)
{
preg_match_all("/[\x80-\xff].|[\x01-\x7f]+/",$str,$r);
$ar = $r[0];
foreach($ar as $k=>$v)
{
if(ord($v[0]) < 128)
$ar[$k] = rawurlencode($v);
else
$ar[$k] = "%u".bin2hex(iconv("UTF-8","UCS-2",$v));
}
return join("",$ar);
}

JS讀cookie的時候,用unescape解碼,
然後就解決cookie中有中文亂碼的問題了。

2.外部JS檔UTF-8編碼問題
當一個HTML頁面或則PHP頁面包含一個外部的JS檔時,
如果HTML頁面或則PHP頁面是UTF-8編碼格式的檔,
外部的JS檔同樣要轉成UTF-8的檔,
否則將出現,沒有包含不成功,調用函數時沒有反應的情況。
點擊編輯器的功能表:“檔”->“另存為”,可以看到當前檔的編碼,確保檔編碼為:UTF-8,
如果是ANSI,需要將編碼改成:UTF-8。

五.FLASH相關的UTF-8編碼問題
FLASH內部對所有字串,預設都是以UTF-8處理
1.FLASH讀文普通本檔(txt,html)
要將文字檔的編碼存為UTF-8
點擊編輯器的功能表:“檔”->“另存為”,可以看到當前檔的編碼,確保檔編碼為:UTF-8,
如果是ANSI,需要將編碼改成:UTF-8。
2.FLASH讀XML文件
要將XML檔的編碼存為UTF-8
點擊編輯器的功能表:“檔”->“另存為”,可以看到當前檔的編碼,確保檔編碼為:UTF-8,
如果是ANSI,需要將編碼改成:UTF-8。
在XML第1行寫:

3.FLASH讀PHP返回資料
如果PHP編碼本身是UTF-8的,直接echo就可以了
如果PHP編碼本身是GB2312的,可以將PHP轉存成UTF-8編碼格式的檔,直接echo就可以了
如果PHP編碼本身是GB2312的,而且不允許改檔的編碼格式,
用下麵的語句將字串轉換成UTF-8的編碼格式
$new_str = iconv("GB2312", "UTF-8", "$str");
再echo就可以了
4.FLASH讀資料庫(MYSQL)的資料
FLASH要通過PHP讀取資料庫中的資料
PHP本身的編碼不重要,關鍵是如果資料庫的編碼是GB2312的話,
需要用下面的語句將字串轉換成UTF-8的編碼格式
$new_str = iconv("GB2312", "UTF-8", "$str");

5.FLASH通過PHP寫資料
一句話,FLASH傳過來的字串是UTF-8格式的,
要轉換成相應的編碼格式,再操作(寫檔、寫資料庫、直接顯示等等)
還是用iconv函數轉換
6.FLASH使用本地編碼(理論上不推薦使用)
如果想讓FLASH不使用UTF-8編碼,而是使用本地編碼
對於中國大陸地區而言,本地編碼是GB2312或GBK
AS程式內,可以添加以下代碼:
System.useCodepage = true;
那麼FLASH內所有字元都是使用GB2312的編碼了
所有導入到FLASH或者從FLASH匯出的資料,都應該做相應的編碼轉換
因為使用本地編碼,會造成使用繁體中文地區的使用者產生亂碼,所以不推薦使用

------------------Dreamweaver 網頁編輯器---------------------------------
設定頁面的標題和編碼方式屬性



標題/編碼方式」頁面屬性選項可讓您根據撰寫網頁所使用的語言,指定專屬的文件編碼方式類型,以及針對該編碼方式類型,指定所要使用的 Unicode 標準化格式。

    選取「修改 > 頁面屬性」,或按一下文字「屬性」檢視窗中的「頁面屬性」按鈕。
    選擇「標題/編碼方式」類別並設定選項。

    標題
        指定出現在「文件」視窗和大多數瀏覽器視窗標題列中的頁面標題。

    文件類型 (DTD)
        會指定文件類型定義。例如,您可以從彈出式選單中選取「XHTML 1.0 Transitional」或「XHTML 1.0 Strict」,使 HTML 文件與 XHTML 相容。

    編碼
        會指定文件中字元所用的編碼方式。

        如果選取 Unicode (UTF-8) 為文件編碼方式,便不需要再使用實體編碼方式,因為 UTF-8 可以安全地呈現所有的字元。但若選取了其他的文件編碼方式,則可能需要實體編碼方式才能夠表示某些字元。如需字元實體的詳細資訊,請參閱 www.w3.org/TR/REC-html40/sgml/entities.html。

    重新載入
        可讓您轉換現有文件的編碼方式,或是以新的編碼方式重新開啟文件。

    Unicode 標準化格式
        只會在您選取 UTF-8 當作文件編碼方式時啟用。Unicode 標準化格式有四種類型。最重要的一種是「標準化格式 C」,因為這是全球資訊網中字元模型 (Character Model) 最常用的格式。為求完整起見,Adobe 也提供其餘三種 Unicode 標準化格式。

        在 Unicode 中,某些字元看起來很相似,但卻能以不同方式儲存於文件中。例如,「ë」(e 母音變化) 可以表示為「e 母音變化」單一字元,也可以表示為「一般拉丁字母 e」+「組合母音變化」兩個字元。Unicode 組合字元是與前一個字元組合一起使用的字元,因此母音變化可能出現在「拉丁字母 e」的上面。這兩種格式的印刷結果看起來完全一樣,但是儲存至檔案的內容互不相同。

        標準化程序是為了確定,能以不同格式來儲存的所有字元全部儲存成相同格式。也就是說,文件中所有的「ë」字元都儲存成單一的「e 母音變化」,或者都儲存成「e」+「組合母音變化」,所以一份文件中不至於同時出現兩種格式。

        如需有關 Unicode 標準化以及可供使用的特定格式之詳細資訊,請查閱 Unicode 網站,網址為:www.unicode.org/reports/tr15。

    包含 Unicode 簽名 (BOM)
        可讓您在文件中包含位元順序標記 (BOM)。BOM 是位於文字檔開頭處的 2 到 4 個位元組,用來識別檔案為 Unicode,而且若有 BOM 的話,也會指出後續位元組的位元順序。由於 UTF-8 沒有位元順序,所以加入 UTF-8 BOM 是選擇性的動作。但對 UTF-16 和 UTF-32 而言則是必要的。

        【出處】http://help.adobe.com/zh_TW/dreamweaver/cs/using/WS4A31B6A6-8F51-4b2a-AC51-3AA1F6F709A4a.html

        【出處】http://www.dotblogs.com.tw/jellycheng/archive/2010/11/18/19533.aspx

        【出處】http://www.jb51.net/article/30064.htm

沒有留言:

張貼留言