2013-03-04 61 views
4

我的腳本是用UTF-8編寫的,它使用的MySQL數據庫表具有排序規則utf8_unicode_ci。現在,如果我想比較$_GET/$_POST中的字符串與腳本/數據庫中的「內部」字符串,或者甚至將某些內容放到數據庫中,我是否必須檢查/修復變量的編碼還是PHP已經爲我執行了這個操作?

如果前者是這種情況,我可以簡單地在腳本的開頭執行以下操作嗎?

function inputToUtf8($string) { 
    $detectedEncoding = mb_detect_encoding($string, 'UTF-8,ISO-8859-1', true); 
    if ($detectedEncoding == 'UTF-8') { 
    return $string; 
    } elseif ($detectedEncoding == 'ISO-8859-1') { 
    return utf8_encode($string); 
    } 
    throw new Exception('Invalid character encoding detected.'); 
} 

foreach ($_GET as &$v) $v = inputToUtf8($v); unset($v); 
foreach ($_POST as &$v) $v = inputToUtf8($v); unset($v); 
+0

我不知道這個函數是否會拋出異常。 mb_detect_string的返回值被解釋爲'檢測到的字符編碼'或者'如果不能從給定字符串檢測到編碼'則返回FALSE'。但是如果字符串不是有效的UTF-8,它總是返回'ISO-8859-1'。 – 2013-03-06 12:59:06

回答

2

PHP不會爲你這樣做,但客戶端瀏覽器通常會這樣做。發送GET/POST數據是HTML頁面編碼的正常情況,所以如果您已經爲HTML頁面正確指定了字符編碼,那麼瀏覽器通常也應該使用相同的字符編碼。

當然,最好確定而不是假設 - 至少如果你需要確定它。

編輯:爲了清楚這一點 - 確保我的意思是過濾出與您期望的字符集不匹配的字符。您應該一次設置,期望並且僅支持一個字符集。

+0

沒有辦法確定,因爲檢測編碼只是猜測。它不會幫助你,只是在檢測到錯誤的編碼時創建另一個潛在的問題。 – amik 2013-03-04 21:44:23

+0

@ user1660584我不是在談論檢測 - 我是在談論如何篩選出未知的字符,如果你需要確保只有正確的字符正在工作。猜猜我可以做得更清楚。 – eis 2013-03-04 21:49:15

+0

那麼,在這種情況下,你不應該使用utf8_encode既不檢測編碼。您可能正在尋找一個刪除所有不需要的字符的正則表達式(它也不清楚什麼是未知字符 - 是的,在UTF8中,您可能具有完全無效的序列,但通常每個charcode都是一些具有某種含義的字符)。 – amik 2013-03-06 18:53:22

1

我建議不檢測編碼,因爲:

  • 所有工作正常的網頁瀏覽器在相同的編碼發送數據,您的網頁。沒有例外。
  • 檢測編碼不是100%準確。一個字符串可以(並且通常是)在多種編碼中有效,因此可能會檢測到錯誤的編碼,並且轉換會造成混亂。
+0

說沒有例外是錯的。也有例外情況,例如1)http頭內容類型,可能存在也可能不存在,因爲用戶可以在本地保存頁面,2)表單接受編碼字符集參數可以與頁面charset相矛盾,3)頁面可以是它指定的不同編碼,4)用戶可以剛剛從瀏覽器選項變爲不同的編碼。但是*通常*數據使用相同的編碼發送。 – eis 2013-03-04 21:55:38

+0

1)好的,不要在HTML頭中指定編碼。好吧,它可能會導致你陷入困境。2)是的,但你仍然知道你的PHP將會得到什麼編碼。 3)那麼頁面也被錯誤地顯示,這通常是更大的問題。 4)是的,他也可以通過telnet發送HTTP請求。 我的觀點是,如果你的頁面被正確寫入,並且用戶沒有試圖破解它,你總是知道你會收到什麼編碼,真的沒有例外。但是,感謝您提供額外的信息,您是真實的,但我擔心這不是這種情況。 – amik 2013-03-06 18:50:45

+0

4日,我看到一個用戶偶然發生的情況,它不必是惡意的。或者由於一些不適當的建議或誤解。我認爲這比使用telnet發送HTTP請求更經常發生。但是,好的,這已經不是了。 :) – eis 2013-03-06 19:17:30