1 (изменено: TRIGUN, 2011-07-01 16:36:23)

Тема: Перекодировка БД (IPB)

Здравствуйте!
Была поставлена цель перекодировать БД форума IPB 2.3.6
В самой базе таблицы имеют различную кодировку: latin1_swedish_ci, utf8_general_ci, cp1251_general_ci.
Основная текстовая информация лежит в таблицах с кодировкой latin1_swedish_ci.
Перекодировать ВСЮ базу и данные в ней нужно именно в utf8_general_ci.
Я взял БД с виртуального хостинга и перенес на локальный, предварительно создав новую БД в кодировке utf8_general_ci.

Ранее я такого никогда не делал, решил воспользоваться подсказками опытных спецов.
Порекомендовали делать все запросами вида:

ALTER TABLE `таблица` CHANGE `поле` `поле` varchar(255) CHARACTER SET BINARY NOT NULL; 
ALTER TABLE `таблица` CHANGE `поле` `поле` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; 
ALTER TABLE `таблица` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

Я пробовал разные способы, слегка все сдвинулось только при таком:

ALTER TABLE `таблица` CHANGE `поле` `поле` varchar(255) CHARACTER SET BINARY NOT NULL; 
ALTER TABLE `таблица` CHANGE `поле` `поле` varchar(255) CHARACTER SET cp1251 COLLATE cp1251_general_ci NOT NULL; 
ALTER TABLE `таблица` DEFAULT CHARACTER SET cp1251 COLLATE cp1251_general_ci;

Т.е. в начале перевел из latin1_swedish_ci в binary, а затем и в cp1251_general_ci.
Далее делаю запрос:

ALTER TABLE `таблица` CHANGE `поле` `поле` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; 
ALTER TABLE `таблица` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

Т.е. тут я перевожу сразу из cp1251_general_ci в utf8_general_ci

ИТОГ: в БД все нормально отображается, а на форуме все русские буквы как ????????

2

Re: Перекодировка БД (IPB)

Хорошо, что в БД теперь данные в порядке. Теперь попробуйте прописать в файле config_global.php строку: $INFO['mysql_codepage'] = 'utf8';

Точно не уверен, но должно работать. Проверьте все ли файлы форума (языковые, шаблоны) у вас в utf-8.

3 (изменено: TRIGUN, 2011-07-01 21:55:00)

Re: Перекодировка БД (IPB)

Hanut сказал:

Хорошо, что в БД теперь данные в порядке. Теперь попробуйте прописать в файле config_global.php строку: $INFO['mysql_codepage'] = 'utf8';

Точно не уверен, но должно работать. Проверьте все ли файлы форума (языковые, шаблоны) у вас в utf-8.

Здравствуйте!
$INFO['mysql_codepage'] = 'utf8'; - я это делал постоянно. И почему то если прописать просто "utf8" то будет бардак на всем форуме, а если поставить дефис "utf-8" то знаки вопросов smile

Про файлы - перекодировка не помогла sad Перевел в utf8 без BOM

Странности:
Я поставил мини-мост и на CMS должны выводится сообщения с форума. ДО перекодировки выводились каракули, НО после перекодировки все встало на свои места. О чем это говорит?

Так же, если я добавляю сообщение, то на форуме оно отображается как нужно(!), но в базе пишутся каракули.

4

Re: Перекодировка БД (IPB)

В общем ломал ломал голову....
В итоге получается так:

Старая информация в БД после конвертации отображается нормально, а новая в каракулях.
На форуме старая информация в вопросиках, а новая нормально...

В чем тут может быть проблема?

5

Re: Перекодировка БД (IPB)

TRIGUN сказал:

если я добавляю сообщение, то на форуме оно отображается как нужно(!), но в базе пишутся каракули.

Думаю здесь придется копаться в коде форума. Поиском по всем файлам форума найдите вхождение функции mysql_connect и сразу после данной функции добавьте строку:

mysql_query('SET NAMES utf8');

Возможно функция mysql_connect будет находиться внутри класса, в этом случае не стоит точно копировать эту строку.

6 (изменено: Hanut, 2011-07-02 21:39:23)

Re: Перекодировка БД (IPB)

Вот что поиск по файлам дал.

файл:
class_db_mysql_client.php

         //-----------------------------------------
         // Connect
         //-----------------------------------------
         
        if ( $this->obj['persistent'] AND ! IPS_MAIN_DB_CLASS_LEGACY )
        {
            $this->connection_id = @mysql_pconnect( $this->obj['sql_host'] ,
                                                   $this->obj['sql_user'] ,
                                                   $this->obj['sql_pass'] ,
                                                   $this->obj['force_new_connection']
                                                );
        }
        else
        { 
            if ( IPS_MAIN_DB_CLASS_LEGACY )
            {
                $this->connection_id = @mysql_connect( $this->obj['sql_host'] ,
                                                      $this->obj['sql_user'] ,
                                                      $this->obj['sql_pass']
                                                    );
            }
            else
            {
                $this->connection_id = @mysql_connect( $this->obj['sql_host'] ,
                                                      $this->obj['sql_user'] ,
                                                      $this->obj['sql_pass'] ,
                                                      $this->obj['force_new_connection']
                                                    );
            }
        }
        mysql_query('SET NAMES utf8', $this->connection_id); // Добавить строку.

файл:
Mysql.php

    /**
     * constructor(string $dsn)
     * Connect to MySQL.
     */
    function DbSimple_Mysql($dsn)
    {
        $p = DbSimple_Generic::parseDSN($dsn);
        if (!is_callable('mysql_connect')) {
            return $this->_setLastError("-1", "MySQL extension is not loaded", "mysql_connect");
        }
        $ok = $this->link = @mysql_connect(
            $p['host'] . (empty($p['port'])? "" : ":".$p['port']),
            $p['user'],
            $p['pass'],
            true
        );
        $this->_resetLastError();
        if (!$ok) return $this->_setDbError('mysql_connect()');
        mysql_query('SET NAMES utf8', $this->link); // Добавить строку.
        $ok = @mysql_select_db(preg_replace('{^/}s', '', $p['path']), $this->link);
        if (!$ok) return $this->_setDbError('mysql_select_db()');
    }

7

Re: Перекодировка БД (IPB)

Попробуйте добавить строку в оба файла, как я проставил в вашем сообщении.

8

Re: Перекодировка БД (IPB)

Hanut сказал:

Попробуйте добавить строку в оба файла, как я проставил в вашем сообщении.

Если честно, я не знаю как верно это сделать.
Вопрос такой, а обязательным условием является конвертация всех языковых файлов в utf8? Может ли это влияет на вывод/ввод данных с БД?

9

Re: Перекодировка БД (IPB)

TRIGUN сказал:

Если честно, я не знаю как верно это сделать.

Я добавил в вашем сообщении две строки, просто пропишите их таким же образом.

TRIGUN сказал:

Вопрос такой, а обязательным условием является конвертация всех языковых файлов в utf8?

Обязательно для всех файлов содержащих НЕ латиницу, в вашем случае, кириллицу. Остальные файлы, такие, как классы - конвертировать не обязательно.

10

Re: Перекодировка БД (IPB)

Hanut сказал:
TRIGUN сказал:

Если честно, я не знаю как верно это сделать.

Я добавил в вашем сообщении две строки, просто пропишите их таким же образом.

TRIGUN сказал:

Вопрос такой, а обязательным условием является конвертация всех языковых файлов в utf8?

Обязательно для всех файлов содержащих НЕ латиницу, в вашем случае, кириллицу. Остальные файлы, такие, как классы - конвертировать не обязательно.

Попробовал все что вы сказали...не помогло...

11

Re: Перекодировка БД (IPB)

TRIGUN сказал:

Попробовал все что вы сказали...не помогло...

В корне хоста добавьте файл .htaccess со строкой:

PHP_VALUE default_charset utf-8

Поищите в файлах форума другие "SET NAMES".

И уточните что именно не работает и как выводится. Сейчас речь должна идти только о форуме.

12

Re: Перекодировка БД (IPB)

Файлы с SET_NAMES:
.../chat/kernel/db.php

    /**
     * Подключение к дб
     *
     */
    public function connect()
    {
        $this->id = mysql_connect($this->hostname,$this->username,$this->password);
        if( !$this->id )
        {
            @elfchat_error('noconnect');
        }
        if(!mysql_select_db($this->dbname, $this->id))
        {
            @elfchat_error('noselect');
        }
        mysql_query("SET NAMES 'utf8'");
    }

...ips_kernel/class_db_mysql_client.php

    function sql_set_collation_and_cp()
    {
        $this->sql_get_version();

        if ( $this->mysql_version >= 40101 )
        {
            $res = mysql_query( "SHOW CHARSET LIKE '" . $this->obj['mysql_codepage']  .  "'", $this->connection_id );
            
            $charset = mysql_fetch_row($res);

            mysql_query( "SET NAMES " . $this->obj['mysql_codepage'], $this->connection_id );
            mysql_query( "SET CHARACTER SET " . $this->obj['mysql_codepage'], $this->connection_id );      
            mysql_query( "SET character_set_connection = " . $this->obj['mysql_codepage'], $this->connection_id );                 
            mysql_query( "SET collation_connection = " . $charset[2], $this->connection_id );
        }
        
        unset( $this->obj['sql_host'] );
        unset( $this->obj['sql_user'] );
        unset( $this->obj['sql_pass'] );
        
        return TRUE;
    }

...ips_kernel/class_db_mysqli_client.php

    function sql_set_collation_and_cp()
    {
        $this->sql_get_version();
        
        if ( $this->mysql_version >= 40101 )
        {
            $res = mysqli_query( $this->connection_id, "SHOW CHARSET LIKE '" . $this->obj['mysql_codepage']  .  "'");
            
            $charset = mysqli_fetch_row($res);

            mysqli_query( $this->connection_id, "SET NAMES " . $this->obj['mysql_codepage'] );
            mysqli_query( $this->connection_id, "SET CHARACTER SET " . $this->obj['mysql_codepage'] );      
            mysqli_query( $this->connection_id, "SET character_set_connection = " . $this->obj['mysql_codepage'] );      
            mysqli_query( $this->connection_id, "SET collation_connection = " . $charset[2] );
        }
                      
        return TRUE;
    }

Вроде все ссылается на codepage в файле конфига.

13

Re: Перекодировка БД (IPB)

Установите в mysql_codepage utf8 (без дефиса) и покажите как кириллица будет выводиться. Проверьте, чтобы в phpMyAdmin везде была кодировка utf8 и кириллица была читаема.

14

Re: Перекодировка БД (IPB)

Hanut сказал:

Установите в mysql_codepage utf8 (без дефиса) и покажите как кириллица будет выводиться. Проверьте, чтобы в phpMyAdmin везде была кодировка utf8 и кириллица была читаема.

Если без дефиса, то форум выдает ошибку + везде вылазит часть кода. В PhPmyadmin кириллица читается нормально.
В общем не знаю в чем тут проблема...может быть просто IPB 2.3.x не в состоянии работать в этой кодировке.

15

Re: Перекодировка БД (IPB)

TRIGUN сказал:

Если без дефиса, то форум выдает ошибку + везде вылазит часть кода.

Даже не знаю что сказать, но это очевидная ошибка форума, кодировка соединения с MySQL должна иметь вид utf8, то есть без дефиса.

Выше вы искали SET NAMES, попробуйте вручную прописать кодировку соединения с MySQL.

Для mysql.

mysql_query( "SET NAMES utf8", $this->connection_id ); // Эту строку отредактировать.
//Закоментировать mysql_query( "SET CHARACTER SET " . $this->obj['mysql_codepage'], $this->connection_id );      
//Закоментировать mysql_query( "SET character_set_connection = " . $this->obj['mysql_codepage'], $this->connection_id );                 
//Закоментировать mysql_query( "SET collation_connection = " . $charset[2], $this->connection_id );

Для mysqli

mysqli_query( $this->connection_id, "SET NAMES utf8" ); // Отредактировать.
//Закоментировать mysqli_query( $this->connection_id, "SET CHARACTER SET " . $this->obj['mysql_codepage'] );      
//Закоментировать mysqli_query( $this->connection_id, "SET character_set_connection = " . $this->obj['mysql_codepage'] );      
//Закоментировать mysqli_query( $this->connection_id, "SET collation_connection = " . $charset[2] );

16

Re: Перекодировка БД (IPB)

Уважаемый!
Я думаю, нужно пересмотреть свои действия. Мне кажется, я допустил ошибку.

Скорее всего я не сконвертировал данные в БД, а просто перевел её в другую кодировку, что собственно эффекта и не дало.
Есть ли стабильные способы конвертации данных из cp1251 в utf8? И в чем суть этого процесса?

17

Re: Перекодировка БД (IPB)

TRIGUN сказал:

Есть ли стабильные способы конвертации данных из cp1251 в utf8? И в чем суть этого процесса?

Все зависит от того, в каком виде данные находятся в БД. Посмотрите исходные данные (до перекодировки) в phpMyAdmin и покажите как выглядит кириллица и скопируйте структуру любой таблицы, чтобы можно было видеть кодировку таблицы и полей.

Если в базе данных содержатся таблицы с разными кодировками, то сохранять и перекодировать их необходимо раздельно.

18

Re: Перекодировка БД (IPB)

В общем я долго ломал голову и сделал так:

Взял дамп базы => открыл нужную таблицу => кинул массив в декодер => раскодированную информацию закинул обратно в таблицу уже в нужной кодировке => закинул дамп

Работает...
--------------------------------------------------------------
Это была первая часть моей истории...теперь вторая.
Делалось это все для того, чтобы поставить интеграционный мост между IPB и Joomla
Раньше так же была Joomla, но более старой версии. Её мне пришлось вырезать и поставить новую.
Проведя успешную интеграцию, я столкнулся с проблемой:

Если к примеру я залогинился на сайте, а затем просто перезагрузил компьютер, то при новом заходе на сайт не работает переход именно на форум и не логинится вообще нигде. Помогает только перезагрузка браузера.

Структура сайта:
www.site.ru
www.site.ru/forum


До этого я разкомментировал библиотеку php_mbstring для более успешной работы пакета интеграции.
В общем с такой проблемой я никогда еще не сталкивался, даже понятия не имею в чем может быть проблема. Ощущение что форум при первом заходе вообще отсутствует и только после перезагрузки браузера, форум становится видно.

19

Re: Перекодировка БД (IPB)

Если таким странным образом ведут себя все браузеры, то проблема где-то в скрипте, но без логов ошибок или хоть чего-то за что можно зацепиться - здесь сложно сказать причину.

20

Re: Перекодировка БД (IPB)

Hanut сказал:

Если таким странным образом ведут себя все браузеры, то проблема где-то в скрипте, но без логов ошибок или хоть чего-то за что можно зацепиться - здесь сложно сказать причину.

Тогда дам еще наводку.
1. После чистки куки или перезагрузки браузера все начинает работать
2. В логах ошибок нет, специально проверял

Получается что просто не пускает по адресу www.site.ru/forum и моментом редиректит, словно каталога "forum" вовсе нет.

21

Re: Перекодировка БД (IPB)

TRIGUN сказал:

1. После чистки куки или перезагрузки браузера все начинает работать

Это похоже на проблему с сессиями. Надо проверить пару моментов:
1) Время на компьютере и на сервере.
2) Каталог для хранения сессий на сервере. В php.ini каталог сессий указывается в директиве session.save_path. Посмотреть его можно в phpinfo().

22

Re: Перекодировка БД (IPB)

Дано
Сайт на Joomla!
Часть таблиц latin1_swedish_ci (5 таблиц) часть на utf8_general_ci (105 таблиц)
должно быть все на  utf8_general_ci
например на  latin1_swedish_ci таблица jos_sefexttexts
Решение
SQL запрос
ALTER TABLE jos_sefexttexts CONVERT TO CHARSET utf8
Вопрос.
Я правильно сделал?

23

Re: Перекодировка БД (IPB)

zfiefnf6rrf сказал:

Я правильно сделал?

Это зависит от того, в каком виде кириллица была в этих таблицах, то есть с какой кодировкой соединения с MySQL данные приходили в таблицы БД.

Самый простой способ перекодировки таких таблиц - это сохранить их отдельно от других (тех что в utf8) в дампе, затем открыть этот дамп в текстовом редакторе и вручную поправить все latin1 на utf8, после чего импортировать дамп обратно.

24

Re: Перекодировка БД (IPB)

Hanut сказал:
zfiefnf6rrf сказал:

Я правильно сделал?

Это зависит от того, в каком виде кириллица была в этих таблицах, то есть с какой кодировкой соединения с MySQL данные приходили в таблицы БД.

Самый простой способ перекодировки таких таблиц - это сохранить их отдельно от других (тех что в utf8) в дампе, затем открыть этот дамп в текстовом редакторе и вручную поправить все latin1 на utf8, после чего импортировать дамп обратно.

а там вообще кирилицы не было

25

Re: Перекодировка БД (IPB)

zfiefnf6rrf сказал:

а там вообще кирилицы не было

Тогда правильно.