我沒有看到在後端使用Unicode以及多語言應用程序前端的代碼頁有任何意義。您可以在整個項目中使用相同的編碼,也可以手動在UTF-8
和windows-1252
之間來回轉換。
我不認爲你有閱讀問題。標籤會從數據庫中截斷,否則您的瀏覽器將顯示垃圾字符。所以這不是PHP/HTML的問題,而是MySQL的問題。在èéàòì
之類的情況下,MySQL肯定能夠從UTF-8轉換爲CP1252(latin1)。但是,如果情況並非如此(如果我們嘗試將同一個字符串從UTF-8轉換爲CP1251),MySQL將顯示一個問號?
。
在你的情況下,我認爲這是一個輸入問題,即標籤被截斷在數據庫中。這怎麼可能?你可能有一個UTF8 PHP和MySQL,但是當你的瀏覽器從加載了這樣的字符集的頁面提交表單時,它會發送windows-1252
字符串。在您的PHP腳本中,您應該將此字符串轉碼爲UTF-8
,然後將其插入數據庫,或者使用SET NAMES 'CP1252'
連接到MySQL。既然你不這樣做,你最終會試圖插入一堆無效的UTF-8字節,所以MySQL會截斷這個字符串,你的標籤是空的。附件是一個測試用例。這裏是test
表
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(128) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
下面是PHP的一部分。請注意,此腳本採用UTF-8編碼,因此出現在其中的每個文字字符串都具有相同的編碼。
// This is a UTF-8 file, so my editor uses UTF-8 and thus each literal
// string is a UTF-8 string, since PHP only has binary strings.
$label = "Référence";
// Now let's translate this string as if it came from a browser submitting
// a form loaded from a cp1252 encoded page
$src = mb_convert_encoding($label, "CP1252", "UTF-8");
// But connect as if I were UTF-8
$db = new PDO('mysql:host=localhost;dbname=test;charset=utf8',
'test', 'test');
// Insert the string
$stmt = $db->prepare('INSERT INTO test (name) VALUES (?)');
$stmt->bindValue(1, $src);
$stmt->execute();
// Read it
header("content-type: text/plain; charset=windows-1252");
foreach($db->query('SELECT * FROM test') as $row)
echo $row['name'] . "\n";
你如何恢復?您可以使用cp1252
字符集連接到MySQL,並讓MySQL爲您翻譯,或者在腳本中對字符串進行轉碼。
正確獲取數據後,您必須提取它們並將其放在HTML頁面上。這次你會遇到同樣的問題,但是相反:在CP1252文檔中顯示一個UTF-8字符串。數據庫中的字節不適用,因爲UTF-8是可變長度編碼,而在CP1252中,字符長度恰好爲1個字節。如果將這些字節直接放入頁面中,瀏覽器將顯示一些隨機字節的亂碼。因此,您再次連接到指定CP1252
字符集的數據庫,以便MySQL負責轉換併爲您提供正確的字節,或者您可以在PHP端自行轉碼字節。或者你最好自己幫忙:在任何地方使用相同的編碼。我建議UTF-8
因爲今天是正確的事情做,但你可以成功地選擇CP1252
因爲它可以代表英語和法語字符(並保存一些存儲,但我不認爲這是一個問題)
也許在整個應用程序中使用UTF-8,而不是在傳統編碼和Unicode之間不斷轉換? – Joey
這是什麼意思* ** **之後的字符**被削減*? – Raffaele
您是否在從數據庫中讀取數據併發送給HTML之間調用任何字符串操作函數?也許你使用了一個PHP的字符串函數,它不知道unicode(例如'strlen'而不是'mb_strlen')。 – martinstoeckli