Pull to refresh

PHP класс для конвертирования кодировки базы Mysql

Reading time4 min
Views583
Недавно я написал скрипт конвертирования Mysql базы из одной кодировки в другую. После, я решил переписать скрипт, создав класс. Теперь можно подключать эту библиотеку в своих скриптах. Использование данного класса показано ниже.


  1. <?php
  2. /**
  3. * Класс конвертирует базу данных Mysql из одной кодировки в другую
  4. */
  5. class convertCharsetDb {
  6. protected $_charsetFrom = 'cp1251';
  7. protected $_charsetTo = 'utf8';
  8. protected $_isInnoDb = true;
  9. private $__db;
  10. protected $_dbParams = array();
  11. protected $_logger = array();
  12. public function __construct($charsetFrom, $charsetTo, $host, $user, $password, $dbName) {
  13. $this->_charsetFrom = $charsetFrom;
  14. $this->_charsetTo = $charsetTo;
  15. // Коннект к БД.
  16. $this->connectToDb($host, $user, $password, $dbName);
  17. }
  18. /**
  19. * метод, конвертирует базу, все таблицы и ячейки таблиц в кодировку $_charsetTo
  20. */
  21. public function convertDb() {
  22. if (false === $this->__db->query('SET NAMES ' . $this->_charsetTo)) {
  23. $this->insertLog(0, 'ERROR SET NAMES');
  24. return false;
  25. }
  26. // Получение списка таблиц.
  27. if (false === ($resultSetTables = $this->__db->query('SHOW TABLES'))) {
  28. $this->insertLog(0, 'ERROR SHOW TABLES');
  29. return false;
  30. }
  31. if ($resultSetTables->num_rows) {
  32. // Обходим таблицы БД.
  33. while ($rowSet = $resultSetTables->fetch_row()) {
  34. if (!$this->changeTableCharset($rowSet[0])) {
  35. $this->insertLog(0, 'ERROR changeTableCharset. Table: ' . $rowSet[0]);
  36. } else {
  37. $this->insertLog(1, 'SUCCESS changeTableCharset. Table: ' . $rowSet[0]);
  38. }
  39. }
  40. }
  41. // Теперь сменить кодировку всей базы.
  42. $_sql = 'ALTER DATABASE `' . $this->_dbParams[3] . '` DEFAULT CHARACTER SET ' . $this->_charsetTo . ' COLLATE ' . $this->_charsetTo . '_general_ci';
  43. if (false === $this->__db->query($_sql)) {
  44. $this->insertLog(0, 'ERROR CHANGE DATABASE CHARSET. DB: ' . $this->_dbParams[3]);
  45. }
  46. }
  47. /**
  48. * Создает временную таблицу на основе структуры таблицы $tableName с необходимой кодировкой.
  49. * Наполняет временную таблицу сконвертированными данными. Удаляет старую таблицу,
  50. * Меняет название временной таблицы на $tableName.
  51. * @param string $tableName
  52. * @return bool
  53. */
  54. public function changeTableCharset($tableName) {
  55. // Получаем выборку запроса на создание таблицы.
  56. if (false === ($createTableRes = $this->__db->query('SHOW CREATE TABLE ' . $tableName))) {
  57. return false;
  58. }
  59. $createTableRow = $createTableRes->fetch_assoc();
  60. // Строка запроса на создание таблицы.
  61. $createTableStr = $createTableRow['Create Table'];
  62. // Меняем тип таблицы. (Опция).
  63. if ($this->_isInnoDb) {
  64. $createTableStr = str_replace('ENGINE=MyISAM', 'ENGINE=InnoDB', $createTableStr);
  65. }
  66. // Смена кодировки у таблицы и ячеек.
  67. // Стоит заметить тот факт, что ячейки могут (МОГУТ!) быть и в других кодировках, отличных
  68. // от $_params['charset_from']. Этот алгоритм не гарантирует перевод таких ячеек таблицы в
  69. // кодировку $_params['charset_to']
  70. $createTableStr = str_replace($this->_charsetFrom, $this->_charsetTo, $createTableStr);
  71. // Меняем название таблицы на временную
  72. $createTableStr = str_replace('CREATE TABLE `' . $tableName . '`', 'CREATE TABLE `' . $tableName . '__tmp`', $createTableStr);
  73. // Добавляем COLLATE, для правильного поиска и сортировки данных.
  74. $createTableStr.= ' COLLATE ' . $this->_charsetTo . '_general_ci';
  75. // Создаем в БД эту таблицу.
  76. if (false === $this->__db->query($createTableStr)) {
  77. return false;
  78. }
  79. // Из текущей таблицы выводим все данные.
  80. $resultSetData = $this->__db->query('SELECT * FROM ' . $tableName);
  81. if ($resultSetData->num_rows) {
  82. // Полученные ряды необходимо обработать.
  83. while ($rowDataSet = $resultSetData->fetch_assoc()) {
  84. $_sqlVariables = $_sqlValues = array();
  85. // Обходим выборку по каждой ячейке.
  86. foreach ($rowDataSet as $rowVariable => $rowValue) {
  87. array_push($_sqlVariables, $rowVariable);
  88. array_push($_sqlValues, $rowValue);
  89. }
  90. // после обработки необходимо вставить данные в таблицу новой базы.
  91. $_sql = 'INSERT INTO `' . $tableName . '__tmp` (' . implode(',', $_sqlVariables) . ') VALUES("' . implode('" , "', $_sqlValues) . '")';
  92. $this->__db->query($_sql);
  93. }
  94. }
  95. // Теперь необходимо удалить старые таблицы.
  96. $_sql = 'DROP TABLE `' . $tableName . '`;';
  97. if (false === $this->__db->query($_sql)) {
  98. return false;
  99. }
  100. // Меняем название временной таблицы в нормальное.
  101. $_sql = 'ALTER TABLE `' . $tableName . '__tmp` RENAME `' . $tableName . '` ;';
  102. if (false === $this->__db->query($_sql)) {
  103. return false;
  104. }
  105. return true;
  106. }
  107. /**
  108. * Создает подключение к бд.
  109. * @param string $host
  110. * @param string $user
  111. * @param string $password
  112. * @param string $dbName
  113. * @return connector
  114. */
  115. public function connectToDb($host, $user, $password, $dbName) {
  116. $this->_dbParams = array($host, $user, $password, $dbName);
  117. return $this->__db = new MySQLi($host, $user, $password, $dbName);
  118. }
  119. public function setFromCharset($charset) {
  120. $this->_charsetFrom = $charset;
  121. }
  122. public function setToCharset($charset) {
  123. $this->_charsetTo = $charset;
  124. }
  125. private function insertLog($type = 0, $message) {
  126. switch ($type) {
  127. case 1:
  128. if (!isset($this->_logger['success'])) {
  129. $this->_logger['success'] = array();
  130. }
  131. array_push($this->_logger['success'], $message);
  132. break;
  133. default:
  134. if (!isset($this->_logger['error'])) {
  135. $this->_logger['error'] = array();
  136. }
  137. array_push($this->_logger['error'], $message);
  138. break;
  139. }
  140. }
  141. public function showLog() {
  142. echo '--------------------------<br />';
  143. echo '--------SUCCESS---------<br />';
  144. if (count($this->_logger['success']))
  145. foreach ($this->_logger['success'] as $i => $message) {
  146. echo ($i + 1) . '. ' . $message . '<br />';
  147. }
  148. echo '--------------------------<br />';
  149. echo '--------ERRORS---------<br />';
  150. if (count($this->_logger['error']))
  151. foreach ($this->_logger['error'] as $i => $message) {
  152. echo ($i + 1) . '. ' . $message . '<br />';
  153. }
  154. }
  155. li style="font-weight: normal; v
Tags:
Hubs:
Total votes 26: ↑17 and ↓9+8
Comments32

Articles