...

вторник, 12 ноября 2013 г.

[Из песочницы] «Кракозябры» в БД или когда «Думать надо было раньше»

На днях столкнулся с глупейшей ситуацией. Запустили один веб-проект, все работает, код пишется и дополняется, базы данных наполняются. Разработка идет на тестовом хосте, затем изменения заливаются на сервер, вся проверка сводится к заходу на сам сайт и тесту всего и всея. Вдруг, выясняется, что буква «ш» не отображается на сайте, а вместо неё два ничего не значащих символа.



Та же история оказалась с буквой «И». Тут же заходим в СУБД на сервере и видим… сплошные «кракозябры», вместо кириллицы. Но латиница записывается нормально.

Конечно все подумали на проблемы с кодировками и естественно это так. Смотрим подробнее… Кодировка таблицы — 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(); //закрываем соединение, что бы открыть его уже для другой таблицы.
};

?>


Вот и все. Скрипт сделал именно то, что было нужно и писался за пару минут, поэтому могут быть удивления, что это же можно сделать более гибким и оптимизированным, а еще и ООП неплохо прикрутить бы.


Надеюсь, что данный скрипт пригодится кому-либо.

Спасибо за внимание.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers. Five Filters recommends:



Комментариев нет:

Отправить комментарий