Система представляет собой приложение PHP, обращающееся к базе данных MySQL. Первые таблицы были созданы со стандартной кодировкой latin1 и заполнены через mysqli в PHP, без установки какой-либо кодировки. PHP-скрипты и данные работают в UTF-8.
Более новые таблицы установили кодировку utf8_bin и перед каждой транзакцией SET CHARACTER SET utf8
отправлено.
Если я посмотрю на более новые таблицы в базе данных mysql (через sql explorer, такой как HeidiSQL), то каждый специальный символ отображается правильно. Однако в каждой более старой таблице типичные ошибки latin1-utf8 видны как Ãœ для ü.
Есть ли простой способ исправить это одним из следующих способов:
SET CHARACTER SET utf8
или же latin1
перед каждым оператором подгонка кодировки таблиц. (просто обходной путь)SET CHARACTER SET utf8
должен быть отправлен в начале каждого подключения MySQL (или, может быть, есть способ установить это как стандарт?)SET CHARACTER SET utf8
перед транзакциями, но неправильное кодирование в проводнике базы данных.Кажется, что база данных принимает все таблицы как utf8 и показывает таблицы latin1, поэтому с неправильными символами. Mysqli принимает все таблицы как latin1, если не указано иначе.
Приложение продуктивно, проблема кодирования не видна пользователю, так как правильная кодировка сообщается mysqli перед каждым оператором. Но я чувствую, что это не очень хорошая практика.
Я признаю, что с настройкой базы данных что-то не так, и я надеюсь узнать, как лучше всего это исправить.
Первые таблицы были созданы со стандартной кодировкой latin1 и заполнены через mysqli в PHP
Таким образом, эти таблицы имеют мусор. Вам нужно восстановить данные?
перед каждой транзакцией отправляется SET CHARACTER SET utf8.
Это бесполезно. Вместо этого делай SET NAMES utf8
один раз после подключения.
Ü
это моджибаке для Ü
, Ищите этот форум для Моджибаке.
Наличие некоторых таблиц latin1 с utf8 байтами, в то время как другие таблицы utf8 — это будет болезненный беспорядок в будущем. Остановись сейчас и наведи порядок. Иди utf8 до конца.
Краткое изложение моджибаке:
SET NAMES latin1
(или же set_charset('latin1')
или …), возможно по умолчанию. (Это должно было быть utf8
.)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 ...;
Хорошо, вы не можете использовать 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 теперь является файлом в кодировке 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!