[英]php's mb_detect_encoding()
首先,我想說我已經閱讀了另一篇關於php的mb_detect_encoding的帖子,這篇文章是關於PHP 中mb_detect_order()的奇怪行為 。 這肯定再確認我通過追蹤和錯誤學到了什么。 但是仍有一些事情讓我感到困惑。
我正在構建一個主要是英文網站的html抓取工具,它們收集數據並將其存儲為UTF-8 XML。 我遇到了一個頁面自我聲明ISO-8859-1字符集的問題,但它包含Windows-1252獨有的字符。 特別是正確的單引號(')0x92。 據我了解,windows-1252是iso-8859-1的超集,它促使我思考為什么要使用utf8_encode()呢? 為什么不使用iconv('Windows-1252','UTF-8',$ str)代替utf8_encode(),因為iso-8859-1中表示的任何內容都會被轉換為windows-1252獨有的字符(即。€,ƒ''“”)
也
$ansi = "€";//euro mark, the code file itself is in ansi
$detected = mb_detect_encoding($ansi, "WINDOWS-1252");// $detected == "Windows-1252"
$detected = mb_detect_encoding('a'.$ansi, "WINDOWS-1252");// $detected == FALSE
$detected = mb_detect_encoding($ansi.'a', "WINDOWS-1252");// $detected == "Windows-1252"
$detected = mb_detect_encoding($ansi.'a', "WINDOWS-1252",TRUE);// $detected == FALSE
為什么會這樣? 如果字符串中的第一個字符不是windows-1252,即使其余部分是,它也會失敗? 這種行為不會使它變得毫無用處嗎? 至於區分iso-8859-1和windows-1252
另一件令我困惑的事情是,我想要檢測ASCII,ISO-8859-1,windows-1252,UTF-8之間的字符集。 是否有可能以一種給我排名最低的方式檢測字符串? (即。
$ascii = "123"; // desired detect result == 'ASCII'
$iso = "é".$ascii; // desired detect result == 'ISO-8859-1'
$ansi = "€".$iso; // desired detect result == 'Windows-1252'
$utf8 = file_get_contents('utf8.txt', true);//$utf8 == '你好123é€', desired detect result == 'UTF-8'
不應該是$ detect_order = array('ASCII','ISO-8859-1','Windows-1252','UTF-8'); 我知道這是不正確的,因為它給了我以下結果
$ascii == 'ASCII'
$iso == 'ISO-8859-1'
$ansi == 'ISO-8859-1'
$utf8 == 'ISO-8859-1'
為什么我的檢測順序('ASCII','ISO-8859-1','Windows-1252','UTF-8')錯誤的我想得到什么?
我得到的最接近的期望回報值是
$ascii == 'ASCII'
$iso == 'ISO-8859-1'
$ansi == 'ISO-8859-1'
$utf8 == 'UTF-8'
以下兩個mb_detect_order數組都給了我上面的值
$detect_order = array('ASCII', 'UTF-8', 'Windows-1252', 'ISO-8859-1');
$detect_order = array('ASCII', 'UTF-8', 'ISO-8859-1', 'Windows-1252');
這讓我感到困惑!
嗯,有人可以對此有所了解嗎? 非常感謝!
這是一個已知的錯誤 。
只有當整個字符串由特定范圍內的高字節字符組成時, Windows-1251
和Windows-1252
才會成功。 這意味着你永遠無法獲得正確的轉換,因為即使是Windows-1252
,文本也會顯示為ISO-8859-1
。
我遇到了從LATIN1
轉換為UTF-8
。 我有許多內容從Microsoft Word粘貼並使用MySQL表的LATIN1
字符集存儲在VARCHAR
字段中。 你可能知道Word將撇號和引號轉換為智能撇號和引號。 它們都不會顯示在屏幕上,因為這些字符未正確轉換。 該文本始終標識為ISO-8859-1
。 為了解決這個問題,我強制從Windows-1252
轉換為UTF-8
並且撇號和引號(以及其他字符)都被正確轉換。
不確定我是否會回答你的所有問題,但我們在這里:
據我了解,windows-1252是iso-8859-1的超集,它促使我思考為什么要使用utf8_encode()呢? 為什么不使用iconv('Windows-1252','UTF-8',$ str)代替utf8_encode(),因為iso-8859-1中表示的任何內容都將被轉換為windows-1252獨有的字符
你不應該打擾ut8_encode。 轉到iconv()或mb_convert_encoding。 ut8_encode僅將ISO-8859-1轉換為UTF-8。 如果你需要在不同的編碼之間進行轉換,你應該使用其他功能。
關於歐元馬克。 不確定是否在某些時候(正式或非正式)添加到ISO-8859-1但下面的聲明都返回true
$ansi = "€";//euro mark, the code file itself is in ansi
$detected = mb_detect_encoding($ansi, "WINDOWS-1252", TRUE);// $detected == "Windows-1252"
echo $detected."<br/>-<br/>";
$detected = mb_detect_encoding($ansi, "ISO-8859-1", TRUE);// $detected == ISO-8859-1
echo $detected."<br/>-<br/>";
$detected = mb_detect_encoding($ansi, "WINDOWS-1252");// $detected == "Windows-1252"
echo $detected."<br/>-<br/>";
$detected = mb_detect_encoding($ansi, "ISO-8859-1");// $detected == ISO-8859-1
echo $detected."<br/>-<br/>";
注意,這是嚴格設置為True或False的結果。 這可能解釋了原因
不應該是$ detect_order = array('ASCII','ISO-8859-1','Windows-1252','UTF-8'); 我知道這是不正確的,因為它給了我以下結果
給你ISO-8859-1。 我注意到你在后一個順序中切換了UTF-8,領先於ISO,這就是為什么它最終給了你UTF-8。
為什么我的檢測順序('ASCII','ISO-8859-1','Windows-1252','UTF-8')錯誤的我想得到什么?
根據php的網站http://us3.php.net/manual/en/function.mb-detect-order.php ,在UTF-8之前設置ISO將始終返回ISO。 檢查他們的無用檢測順序示例。
從我所看到的情況來看,似乎如果你同時擁有ISO-8859-1和Windows-1252,你將獲得ISO。 如果你拿出一個或另一個,你將得到兩個剩下的東西。 所以下面最后2個的位置似乎沒有什么區別
$ detect_order = array('ASCII','UTF-8','Windows-1252','ISO-8859-1'); $ detect_order = array('ASCII','UTF-8','ISO-8859-1','Windows-1252');
€符號不是utf8編碼的一部分!
你必須把它作為€!
或編碼到windows-1252或iso-8859-15(與iso-8859-1相同,但有符號)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.