本来想着用SHOW CREATE TABLE + ergodic 来做备份的但是发现如果Table 有 comment 而且还是乱码的话,会导致SHOW CREATE TABLE 出来的脚本缺少一个符号。所以有了这个版本。
  1. /**
  2. * database connect
  3. */
  4. private $_db;
  5. private $_resource;
  6. /**
  7. * create table structure sql
  8. */
  9. private $_create_table = '';
  10. public function __construct($host = '', $user = '', $pass = '', $db = '', $port = 3306) {
  11. if (empty($host) || empty($user)) {
  12. } else {
  13. $this->real_connect($host, $user, $pass, $db, $port);
  14. }
  15. }
  16. public function init() {
  17. return $this;
  18. }
  19. /**
  20. * 连接数据库
  21. */
  22. public function real_connect($host, $user, $pass, $db = '', $port = 3306) {
  23. $this->_db = mysql_connect($host . ':' . $port, $user, $pass);
  24. if ($db) {
  25. $this->select_db($db);
  26. }
  27. return $this->init();
  28. }
  29. /**
  30. * 选择数据库
  31. */
  32. public function select_db($db) {
  33. if (mysql_select_db($db, $this->_db)) {
  34. return true;
  35. }
  36. }
  37. /**
  38. * 查询语句
  39. */
  40. public function query($sql) {
  41. if ($this->_db) {
  42. if ($this->_resource = mysql_query($sql, $this->_db)) {
  43. return $this->init();
  44. }
  45. }
  46. throw new Exception($this->get_error());
  47. }
  48. /**
  49. * 获取结果集
  50. */
  51. public function fetch_array($arg = MYSQL_BOTH) {
  52. $result = array();
  53. if ($this->_resource && !mysql_errno($this->_db)) {
  54. while ($rs = mysql_fetch_array($this->_resource, $arg)) {
  55. $result[] = $rs;
  56. }
  57. }
  58. return $result;
  59. }
  60. /**
  61. * 获取错误
  62. */
  63. public function get_error() {
  64. return mysql_errno($this->_db) . ": " . mysql_error($this->_db). "\n";
  65. }
  66. /**
  67. * 显示数据表
  68. */
  69. public function show_tables($table = '') {
  70. $sql = "SHOW TABLES";
  71. $sql .= $table ? " LIKE '{$table}'" : '';
  72. $result = $this->query($sql)->fetch_array(MYSQL_ASSOC);
  73. return $result;
  74. }
  75. /**
  76. * 显示数据表字段
  77. */
  78. public function show_columns($table) {
  79. if (empty($table)) {
  80. return array();
  81. }
  82. $sql = "SHOW FULL COLUMNS FROM {$table}";
  83. $result = $this->query($sql)->fetch_array(MYSQL_ASSOC);
  84. return $result;
  85. }
  86. /**
  87. * 显示数据表状态
  88. */
  89. public function show_table_status($table) {
  90. if (empty($table)) {
  91. return array();
  92. }
  93. $result = $this->query("SHOW TABLE STATUS LIKE '{$table}'")->fetch_array(MYSQL_ASSOC);
  94. $result = reset($result);
  95. return $result;
  96. }
  97. /**
  98. * 显示数据表结构
  99. */
  100. public function show_create_table($table) {
  101. if (empty($table)) {
  102. return '';
  103. }
  104. $this->_create_table = "CREATE TABLE IF NOT EXISTS `{$table}`(" . PHP_EOL;
  105. $table_status = $this->show_table_status($table);
  106. $columns = $this->show_columns($table);
  107. foreach ($columns AS $col) {
  108. $this->_create_table .= "`{$col['Field']}` {$col['Type']} NOT NULL {$col['Extra']}," . PHP_EOL;
  109. }
  110. $this->_create_table .= $this->create_indexSyntax($table);
  111. $char = substr($table_status['Collation'], 0, strpos($table_status['Collation'], '_'));
  112. $table_status['Auto_increment'] = $table_status['Auto_increment'] ? $table_status['Auto_increment'] : 0;
  113. $this->_create_table .= ")Engine={$table_status['Engine']} AUTO_INCREMENT={$table_status['Auto_increment']} DEFAULT CHARSET={$char};" . str_repeat(PHP_EOL, 3);
  114. return $this->_create_table;
  115. }
  116. /**
  117. * 显示触发器
  118. */
  119. public function show_constraint($db_name) {
  120. if (empty($db_name)) {
  121. return array();
  122. }
  123. $sql = "SELECT a.CONSTRAINT_NAME AS constrint_name, a.TABLE_name AS table_name, a.COLUMN_NAME AS column_name, a.REFERENCED_TABLE_NAME as referenced_table_name, a.REFERENCED_COLUMN_NAME AS referenced_column_name, b.UPDATE_RULE as update_rule, b.DELETE_RULE AS delete_rule FROM information_schema.KEY_COLUMN_USAGE AS a LEFT JOIN information_schema.REFERENTIAL_CONSTRAINTS AS b ON a.constraint_name=b.constraint_name WHERE a.constraint_schema = '{$db_name}' AND a.POSITION_IN_UNIQUE_CONSTRAINT = 1";
  124. $result = $this->query($sql)->fetch_array(MYSQL_ASSOC);
  125. }
  126. /**
  127. * 显示索引
  128. */
  129. public function show_index($table) {
  130. if (empty($table)) {
  131. return array();
  132. }
  133. $sql = "SHOW INDEX FROM {$table}";
  134. $result = $this->query($sql)->fetch_array(MYSQL_ASSOC);
  135. return $result;
  136. }
  137. /**
  138. * 显示数据库结构
  139. */
  140. public function show_database_char() {
  141. $sql = "SHOW VARIABLES LIKE 'character_set_database'";
  142. $char = $this->query($sql)->fetch_array(MYSQL_ASSOC);
  143. return reset($char);
  144. }
  145. /**
  146. * 创建索引语法
  147. */
  148. public function create_indexSyntax($table) {
  149. if (empty($table)) {
  150. return array();
  151. }
  152. $indexing = $this->show_index($table);
  153. $syntax = array();
  154. $indexSyntax = array();
  155. foreach ($indexing as $index) {
  156. $syntax[$index['Index_type']][$index['Key_name']][] = $index['Column_name'];
  157. }
  158. foreach ($syntax as $index_type => $index_value) {
  159. foreach ($index_value as $key_name => $columns) {
  160. if ($key_name == 'PRIMARY') {
  161. $indexSyntax[] = 'PRIMARY KEY (`' . implode("`,`", $columns) . '`)';
  162. } else {
  163. if ($index_type == 'FULLTEXT') {
  164. $indexSyntax[] = "FULLTEXT KEY `{$key_name}` (`" . implode("`,`", $columns) . '`)';
  165. } else{
  166. $indexSyntax[] = "KEY `{$key_name}` USING {$index_type} (`" . implode("`,`", $columns) . '`)';
  167. }
  168. }
  169. }
  170. }
  171. return implode(',' . PHP_EOL, $indexSyntax) . PHP_EOL;
  172. }
  173. /**
  174. * 创建 insert 语法
  175. */
  176. public function create_insertSyntax($table) {
  177. if (empty($table)) {
  178. return '';
  179. }
  180. $sql = "SELECT * FROM {$table}";
  181. $result = $this->query($sql)->fetch_array(MYSQL_ASSOC);
  182. $insertStr = '';
  183. if ($result) {
  184. $first = reset($result);
  185. $key = implode('`,`', array_keys($first));
  186. $insert = "INSERT INTO `{$table}` (`{$key}`) VALUES ";
  187. $valuesStr = array();
  188. foreach ($result as $value) {
  189. $values = array();
  190. foreach ($value as $v) {
  191. $v = mysql_real_escape_string($v);
  192. $values[] = preg_replace("#\\\+#", "\\", $v);
  193. }
  194. $valuesStr[] = "('" . implode("','", $values) . "')";
  195. }
  196. $valuesStr = array_chunk($valuesStr, 5000);
  197. foreach ($valuesStr as $str) {
  198. $insertStr .= $insert . implode(',', $str) . ';' . PHP_EOL;
  199. }
  200. }
  201. return $insertStr . str_repeat(PHP_EOL, 3);
  202. }
  203. }
  204. $export = '';
  205. $test = new MysqlExport('localhost', 'root', '', 'pm_cms');
  206. $char = $test->show_database_char();
  207. $test->query("SET NAMES {$char['Value']}");
  208. $tables = $test->show_tables();
  209. foreach ($tables as $table) {
  210. list($table_name) = array_values($table);
  211. $export .= $test->show_create_table($table_name);
  212. $export .= $test->create_insertSyntax($table_name);
  213. }
  214. $fp = fopen('pm_cms.sql', 'w');
  215. fwrite($fp, $export);
  216. fclose($fp);
  217. ?>
复制代码


09-17 13:36