Недавно я написал скрипт конвертирования Mysql базы из одной кодировки в другую. После, я решил переписать скрипт, создав класс. Теперь можно подключать эту библиотеку в своих скриптах. Использование данного класса показано ниже.
- <?php
- /**
- * Класс конвертирует базу данных Mysql из одной кодировки в другую
- */
- class convertCharsetDb {
- protected $_charsetFrom = 'cp1251';
- protected $_charsetTo = 'utf8';
- protected $_isInnoDb = true;
- private $__db;
- protected $_dbParams = array();
- protected $_logger = array();
- public function __construct($charsetFrom, $charsetTo, $host, $user, $password, $dbName) {
- $this->_charsetFrom = $charsetFrom;
- $this->_charsetTo = $charsetTo;
- // Коннект к БД.
- $this->connectToDb($host, $user, $password, $dbName);
- }
- /**
- * метод, конвертирует базу, все таблицы и ячейки таблиц в кодировку $_charsetTo
- */
- public function convertDb() {
- if (false === $this->__db->query('SET NAMES ' . $this->_charsetTo)) {
- $this->insertLog(0, 'ERROR SET NAMES');
- return false;
- }
- // Получение списка таблиц.
- if (false === ($resultSetTables = $this->__db->query('SHOW TABLES'))) {
- $this->insertLog(0, 'ERROR SHOW TABLES');
- return false;
- }
- if ($resultSetTables->num_rows) {
- // Обходим таблицы БД.
- while ($rowSet = $resultSetTables->fetch_row()) {
- if (!$this->changeTableCharset($rowSet[0])) {
- $this->insertLog(0, 'ERROR changeTableCharset. Table: ' . $rowSet[0]);
- } else {
- $this->insertLog(1, 'SUCCESS changeTableCharset. Table: ' . $rowSet[0]);
- }
- }
- }
- // Теперь сменить кодировку всей базы.
- $_sql = 'ALTER DATABASE `' . $this->_dbParams[3] . '` DEFAULT CHARACTER SET ' . $this->_charsetTo . ' COLLATE ' . $this->_charsetTo . '_general_ci';
- if (false === $this->__db->query($_sql)) {
- $this->insertLog(0, 'ERROR CHANGE DATABASE CHARSET. DB: ' . $this->_dbParams[3]);
- }
- }
- /**
- * Создает временную таблицу на основе структуры таблицы $tableName с необходимой кодировкой.
- * Наполняет временную таблицу сконвертированными данными. Удаляет старую таблицу,
- * Меняет название временной таблицы на $tableName.
- * @param string $tableName
- * @return bool
- */
- public function changeTableCharset($tableName) {
- // Получаем выборку запроса на создание таблицы.
- if (false === ($createTableRes = $this->__db->query('SHOW CREATE TABLE ' . $tableName))) {
- return false;
- }
- $createTableRow = $createTableRes->fetch_assoc();
- // Строка запроса на создание таблицы.
- $createTableStr = $createTableRow['Create Table'];
- // Меняем тип таблицы. (Опция).
- if ($this->_isInnoDb) {
- $createTableStr = str_replace('ENGINE=MyISAM', 'ENGINE=InnoDB', $createTableStr);
- }
- // Смена кодировки у таблицы и ячеек.
- // Стоит заметить тот факт, что ячейки могут (МОГУТ!) быть и в других кодировках, отличных
- // от $_params['charset_from']. Этот алгоритм не гарантирует перевод таких ячеек таблицы в
- // кодировку $_params['charset_to']
- $createTableStr = str_replace($this->_charsetFrom, $this->_charsetTo, $createTableStr);
- // Меняем название таблицы на временную
- $createTableStr = str_replace('CREATE TABLE `' . $tableName . '`', 'CREATE TABLE `' . $tableName . '__tmp`', $createTableStr);
- // Добавляем COLLATE, для правильного поиска и сортировки данных.
- $createTableStr.= ' COLLATE ' . $this->_charsetTo . '_general_ci';
- // Создаем в БД эту таблицу.
- if (false === $this->__db->query($createTableStr)) {
- return false;
- }
- // Из текущей таблицы выводим все данные.
- $resultSetData = $this->__db->query('SELECT * FROM ' . $tableName);
- if ($resultSetData->num_rows) {
- // Полученные ряды необходимо обработать.
- while ($rowDataSet = $resultSetData->fetch_assoc()) {
- $_sqlVariables = $_sqlValues = array();
- // Обходим выборку по каждой ячейке.
- foreach ($rowDataSet as $rowVariable => $rowValue) {
- array_push($_sqlVariables, $rowVariable);
- array_push($_sqlValues, $rowValue);
- }
- // после обработки необходимо вставить данные в таблицу новой базы.
- $_sql = 'INSERT INTO `' . $tableName . '__tmp` (' . implode(',', $_sqlVariables) . ') VALUES("' . implode('" , "', $_sqlValues) . '")';
- $this->__db->query($_sql);
- }
- }
- // Теперь необходимо удалить старые таблицы.
- $_sql = 'DROP TABLE `' . $tableName . '`;';
- if (false === $this->__db->query($_sql)) {
- return false;
- }
- // Меняем название временной таблицы в нормальное.
- $_sql = 'ALTER TABLE `' . $tableName . '__tmp` RENAME `' . $tableName . '` ;';
- if (false === $this->__db->query($_sql)) {
- return false;
- }
- return true;
- }
- /**
- * Создает подключение к бд.
- * @param string $host
- * @param string $user
- * @param string $password
- * @param string $dbName
- * @return connector
- */
- public function connectToDb($host, $user, $password, $dbName) {
- $this->_dbParams = array($host, $user, $password, $dbName);
- return $this->__db = new MySQLi($host, $user, $password, $dbName);
- }
- public function setFromCharset($charset) {
- $this->_charsetFrom = $charset;
- }
- public function setToCharset($charset) {
- $this->_charsetTo = $charset;
- }
- private function insertLog($type = 0, $message) {
- switch ($type) {
- case 1:
- if (!isset($this->_logger['success'])) {
- $this->_logger['success'] = array();
- }
- array_push($this->_logger['success'], $message);
- break;
- default:
- if (!isset($this->_logger['error'])) {
- $this->_logger['error'] = array();
- }
- array_push($this->_logger['error'], $message);
- break;
- }
- }
- public function showLog() {
- echo '--------------------------<br />';
- echo '--------SUCCESS---------<br />';
- if (count($this->_logger['success']))
- foreach ($this->_logger['success'] as $i => $message) {
- echo ($i + 1) . '. ' . $message . '<br />';
- }
- echo '--------------------------<br />';
- echo '--------ERRORS---------<br />';
- if (count($this->_logger['error']))
- foreach ($this->_logger['error'] as $i => $message) {
- echo ($i + 1) . '. ' . $message . '<br />';
- }
- }
li style="font-weight: normal; v