2015-08-25 47 views
0

該系統是一個訪問MySQL數據庫的PHP應用程序。第一個表格使用標準的latin1編碼創建,並通過PHP中的mysqli填充,但不設置任何編碼。 PHP腳本和數據都以UTF-8工作。如何清理MySQL表中的編碼

較新的表格已將編碼設置爲utf8_bin,並在每個事務前發送SET CHARACTER SET utf8

如果我看一下mysql數據庫中的新表(通過像HeidiSQL這樣的SQL資源管理器),每個特殊字符都可以正確顯示。但是,在每個舊錶中,典型的latin1-utf8錯誤都可以看到,例如ü。

是否有一個簡單的方法來解決這個問題就像在下列方式之一:

  • 固定的編碼爲每個表,以便在SQL Explorer中正常顯示,但保留PHP代碼,因爲它是(SET CHARACTER SET utf8latin1在每個語句前面,適合表格編碼(僅僅是一種解決方法)
  • 將編碼切換到utf8所有表格 - >現在SET CHARACTER SET utf8必須在每個mysqli連接的開始時發送(或者可能有一種方法可以將其設置爲標準?)
  • 開關e爲所有表填入latin1 - >不需要在事務前發送SET CHARACTER SET utf8,但在數據庫瀏覽器中編碼錯誤。

看起來好像數據庫將所有表格視爲utf8並顯示latin1表格,因此具有錯誤的字符。如果沒有告訴別人,Mysqli會將所有表格視爲latin1。

該應用程序是高效的,編碼問題對用戶不可見,因爲正確的編碼被告知mysqli在每個語句前面。但我覺得這不是一個好習慣。

我意識到數據庫的設置存在問題,我希望能夠學習解決這個問題的最佳實踐。

回答

0

第一表用的標準latin1編碼創建並經由mysqli的PHP中

所以,這些表具有垃圾填充。你需要恢復數據嗎?

在每個事務之前發送SET CHARACTER SET utf8。

這沒用。相反,連接後執行SET NAMES utf8

Ãœ是Mojibake爲Ü。搜索此Mojibake論壇。

有一些utf8字節的表latin1,而其他表是utf8 - 這將是一個痛苦的混亂。現在停下來清理這個爛攤子。一路走utf8。

變爲亂碼的總結:

  • 在客戶端你擁有的字節UTF8(好)的正確編碼。
  • 您與SET NAMES latin1(或set_charset('latin1')或...)連接,可能是默認情況下。 (它應該是utf8。)
  • xx表中的列被宣佈爲CHARACTER SET latin1。 (或者它可能是從表格/數據庫繼承的。)(應該是utf8。)
  • 表中的列可能已經或可能不是CHARACTER SET utf8,但應該是這樣的。

如果需要修復的數據需要「2步ALTER」,像

ALTER TABLE Tbl MODIFY COLUMN col VARBINARY(...) ...; 
ALTER TABLE Tbl MODIFY COLUMN col VARCHAR(...) ... CHARACTER SET utf8 ...; 
0

好吧,你不能使用mysqldump創建一個.sql文件有關表,就像給你HeidiSQL中的垃圾字符一樣。

但是,您可以使用PHP腳本來創建一個.sql文件,其中包含與您的PHP應用程序中相同的錯誤字符集。這PHP腳本應該做到以下幾點:

mb_internal_encoding("UTF-8"); 
$link = mysqli_connect('localhost', 'root', ''); 

mysqli_set_charset($link, "latin1"); 

$result = mysqli_query($link, "SELECT * FROM table1", MYSQLI_USE_RESULT); 
while($row = mysqli_fetch_assoc($result)) 
{ 
    # Generate INSERT statements for table1 using some PHP logic, and write these into a new file, named e.g. fixencoding.sql 
} 
mysqli_free_result($result); 
mysqli_query($link, "DELETE * FROM table1"); 
mysqli_query($link, "ALTER TABLE table1 COLLATE='utf8_general_ci'"); 

$result = mysqli_query($link, "SELECT * FROM table2", MYSQLI_USE_RESULT); 
while($row = mysqli_fetch_assoc($result)) 
{ 
    # Generate INSERT statements for table2 and append these into the .sql file created above 
} 
mysqli_free_result($result); 
mysqli_query($link, "DELETE * FROM table2"); 
mysqli_query($link, "ALTER TABLE table2 COLLATE='utf8_general_ci'"); 

# etc. - repeat above steps for every broken table 

mysqli_close($link); 

創建的fixencoding.sql文件現在沒有BOM的UTF-8編碼的文件,您可以導入使用的mysql.exe:

C:\path\to\mysql\bin\mysql.exe -hlocalhost -uroot name-of-database <fixencoding.sql 

如果所有順利的話,你的PHP應用程序應該包含正確的MySQL的字符集:

mysqli_set_charset($link, 'utf8'); 

此外,HeidiSQL以及其他客戶端應顯示真實的UTF-8字符。

這一切都沒有經過測試!不要忘記首先做一個幹運行,通過註釋DELETE和ALTER查詢!