На днях столкнулся с глупейшей ситуацией. Запустили один веб-проект, все работает, код пишется и дополняется, базы данных наполняются. Разработка идет на тестовом хосте, затем изменения заливаются на сервер, вся проверка сводится к заходу на сам сайт и тесту всего и всея. Вдруг, выясняется, что буква «ш» не отображается на сайте, а вместо неё два ничего не значащих символа.
Та же история оказалась с буквой «И». Тут же заходим в СУБД на сервере и видим… сплошные «кракозябры», вместо кириллицы. Но латиница записывается нормально.
Конечно все подумали на проблемы с кодировками и естественно это так. Смотрим подробнее… Кодировка таблицы — UTF-8, кодировка нужных столбцов — UTF-8, кодировка в заголовках страницы — UTF-8, кодировка в браузере — UTF-8. Ну и конечно подвело промежуточное звено, кодировка соединения — cp1251. А все лишь потому, что не проверили идентичность настроек тестового и рабочего сервера БД. Глупая ошибка, но данных в БД уже полно и надо как-то их вернуть. Прогуглив все, что можно, было найдено несколько интересных sql-запросов, способы с шаманством кодировок в дампах, с помощью блокнота, и один php-скрипт, который отработав безошибочно, просто выдал те же иероглифы. Что то не помогло, что то просто не подходит.
Моё решение банальное, но я не нашел подобного на просторах сети.
Пишем маленький php скрипт перегона нужных таблиц в нужный формат.
<?php
define('BD_HOST','localhost');
define('BD_PASS','password');
define('BD_LOGIN','login'); //доступ к БД
define('BD_FROM','bd1'); //исходная БД
define('BD_IN','bd2'); //конечная БД
$tables = array ( 'table1',
'table2',
'table3',
'table4',
'table5'); //список нужных таблиц для конвертирования, эти таблицы должны быть как в исходной, так и в конечной БД(в конечной, должны быть пустыми)
foreach ($tables as $table) {
mysql_connect(BD_HOST,BD_LOGIN,BD_PASS);
mysql_select_db(BD_FROM);
$query_select_from = "SELECT * FROM $table;";
$result = mysql_query($query_select_from);
mysql_close(); //запросили все косячные данные и закрыли соединение
mysql_connect(BD_HOST,BD_LOGIN,BD_PASS);
mysql_select_db(BD_IN);
mysql_query('set character_set_client="utf8"');
mysql_query('set character_set_results="utf8"');
mysql_query('set collation_connection="utf8_general_ci"');
mysql_query("set names utf8"); //открыли новое соединение, но уже указав все недостающие настройки, из за которых произошло такое недопущение
while ($t = mysql_fetch_assoc($result)) {
$values = '';
$f = false;
foreach($t as $val) {
$p = ($f)?',':'';
$f = true;
$add = (is_int($val))?"$val":"'$val'";
$values.= "$p $add";
};
$insert_in = "INSERT $table VALUES($values)";
mysql_query($insert_in); //запись прочтенной строки, уже в нормальном соединении
};
mysql_close(); //закрываем соединение, что бы открыть его уже для другой таблицы.
};
?>
Вот и все. Скрипт сделал именно то, что было нужно и писался за пару минут, поэтому могут быть удивления, что это же можно сделать более гибким и оптимизированным, а еще и ООП неплохо прикрутить бы.
Надеюсь, что данный скрипт пригодится кому-либо.
Спасибо за внимание.
Автор: SaGrok