2012-09-27 103 views
2

我有一個具有翻譯功能here的頁面。我的問題在於,當我將該語言翻譯成法語時,由於該頁面沒有正確解釋該單詞,所以這些單詞被切斷。我檢查了與我的問題相關的帖子,但沒有一個能夠工作。包含非ASCII字符的字符串被PHP/MySQL截斷

在我的網頁,我把這些東西:

  • header ('Content-Type:text/html; charset=WINDOWS-1252'); - >這只是堅持啓動編碼。我認爲這是可選的,但我仍然使用它。
  • <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
  • 等效翻譯是從數據庫表名牽強:標籤標籤的表類型是InnoDB,其中utf8 - UTF-8 Unicode作爲默認字符集。

之後的字符正在被切斷。我需要做什麼才能正確顯示字符?謝謝!

+4

也許在整個應用程序中使用UTF-8,而不是在傳統編碼和Unicode之間不斷轉換? – Joey

+0

這是什麼意思* ** **之後的字符**被削減*? – Raffaele

+0

您是否在從數據庫中讀取數據併發送給HTML之間調用任何字符串操作函數?也許你使用了一個PHP的字符串函數,它不知道unicode(例如'strlen'而不是'mb_strlen')。 – martinstoeckli

回答

1

我的建議是在整個過程中使用相同的編碼。使用UTF-8作爲標題和元標記中的字符集。

+0

它仍然不能解釋爲什麼零件缺失。這不可能僅僅因爲頁面編碼而發生。 – Joey

+0

好的,所以我將標題和元標記值更改爲 header('Content-Type:text/html; charset = utf-8'); 仍然無法正常工作。 – kimbebot

+0

我的意思是翻譯並不是不起作用。 – kimbebot

2

我沒有看到在後端使用Unicode以及多語言應用程序前端的代碼頁有任何意義。您可以在整個項目中使用相同的編碼,也可以手動在UTF-8windows-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因爲它可以代表英語和法語字符(並保存一些存儲,但我不認爲這是一個問題)

0

它在我看來,你的數據沒有正確存儲在數據庫中。如果您正在使用mysqli,則可以在讀取或寫入數據庫之前嘗試設置連接對象的字符集。

// tells the mysqli connection to deliver UTF-8 encoded strings. 
$db = new mysqli($dbHost, $dbUser, $dbPassword, $dbName); 
$db->set_charset('utf8'); 

對於其他數據庫,請參閱​​。也許有必要再次插入法語textes(使用此設置),因爲現有的textes現在可能無效。

你的鏈接示例頁面被正確使用UTF-8(文件格式)編碼的,雖然你的meta標籤是有點不正確:

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

<!是不是一個註釋掉,你會寫改爲<!--。最好的做法是僅爲UTF-8聲明一次,並刪除其他元標記。

+0

這似乎是一個*被盜的答案*給我。而且,這個問題清楚地表明他希望在前端使用'cp1252',所以頁面正確的UTF-8 *只是一些隨機性。你可以在整個頁面看到'',所以代碼必須真正搞砸了。 – Raffaele

+0

@Raffaele - 從來沒有想成爲一個小偷,我需要一些時間來鍵入答案,所以我沒有看到你的答案。與你想要指出的答案相反,必須將charset設置爲**連接對象**,而不是數據庫配置。因爲我在示例中看到了不同的元標記,我假定kimbebot不反對使用UTF-8,並且不同的標記會干預。如果你看鏈接的文章,你可以看到,這不是一個自發的答案,我自己也有這個問題,並花了相當一段時間寫文章。 – martinstoeckli

+0

@Raffaele - 順便說一句,閱讀你的答案也需要一些時間。但我喜歡它,所以你有我的投票... – martinstoeckli