ExportController.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <?php
  2. namespace backup\controllers;
  3. use backup\models\Database;
  4. use yii\base\Exception;
  5. use yii\data\ArrayDataProvider;
  6. use yii\web\Controller;
  7. use yii\web\Response;
  8. class ExportController extends Controller
  9. {
  10. public function actionIndex()
  11. {
  12. $db = \Yii::$app->db;
  13. $list = $db->createCommand('SHOW TABLE STATUS')->queryAll();
  14. $list = array_map('array_change_key_case', $list);
  15. $dataProvider = new ArrayDataProvider([
  16. 'allModels' => $list,
  17. 'pagination' => false
  18. ]);
  19. return $this->render('index', [
  20. 'dataProvider' => $dataProvider
  21. ]);
  22. }
  23. /**
  24. * 优化表
  25. * @param string $tables 表名
  26. * @return array
  27. * @throws Exception
  28. */
  29. public function actionOptimize($tables = null)
  30. {
  31. \Yii::$app->response->format = Response::FORMAT_JSON;
  32. if($tables) {
  33. $db = \Yii::$app->db;
  34. if(is_array($tables)){
  35. $tables = implode('`,`', $tables);
  36. $list = $db->createCommand("OPTIMIZE TABLE `{$tables}`")->queryAll();
  37. if($list){
  38. return [
  39. 'message' => '数据表优化完成'
  40. ];
  41. } else {
  42. throw new Exception('数据表优化出错请重试!');
  43. }
  44. } else {
  45. $list = $db->createCommand("OPTIMIZE TABLE `{$tables}`")->queryAll();
  46. if($list){
  47. return [
  48. 'message' => "数据表'{$tables}'优化完成!"
  49. ];
  50. } else {
  51. throw new Exception("数据表'{$tables}'优化出错请重试!");
  52. }
  53. }
  54. } else {
  55. throw new Exception('请指定要优化的表');
  56. }
  57. }
  58. /**
  59. * 修复表
  60. * @param String $tables 表名
  61. */
  62. public function actionRepair($tables = null)
  63. {
  64. \Yii::$app->response->format = Response::FORMAT_JSON;
  65. if($tables) {
  66. $db = \Yii::$app->db;
  67. if(is_array($tables)){
  68. $tables = implode('`,`', $tables);
  69. $list = $db->createCommand("REPAIR TABLE `{$tables}`")->queryAll();
  70. if($list){
  71. return [
  72. 'message' => "数据表修复完成!"
  73. ];
  74. } else {
  75. throw new Exception('数据表修复出错请重试');
  76. }
  77. } else {
  78. $list = $db->createCommand("REPAIR TABLE `{$tables}`")->queryAll();
  79. if($list){
  80. return [
  81. 'message' => "数据表'{$tables}'修复完成!"
  82. ];
  83. } else {
  84. throw new Exception("数据表'{$tables}'修复出错请重试!");
  85. }
  86. }
  87. } else {
  88. throw new Exception("请指定要修复的表");
  89. }
  90. }
  91. public function actionInit()
  92. {
  93. \Yii::$app->response->format = Response::FORMAT_JSON;
  94. $tables = \Yii::$app->request->post('tables');
  95. $path = \Yii::$app->controller->module->params['DATA_BACKUP_PATH'];
  96. if(!is_dir($path)){
  97. mkdir($path, 0755, true);
  98. }
  99. //读取备份配置
  100. $config = [
  101. 'path' => realpath($path) . DIRECTORY_SEPARATOR,
  102. 'part' => \Yii::$app->controller->module->params['DATA_BACKUP_PART_SIZE'],
  103. 'compress' => \Yii::$app->controller->module->params['DATA_BACKUP_COMPRESS'],
  104. 'level' => \Yii::$app->controller->module->params['DATA_BACKUP_COMPRESS_LEVEL']
  105. ];
  106. //检查是否有正在执行的任务
  107. $lock = "{$config['path']}backup.lock";
  108. if(is_file($lock)){
  109. return ['status' => 0, 'info' => '检测到有一个备份任务正在执行,请稍后再试!'];
  110. } else {
  111. //创建锁文件
  112. file_put_contents($lock, time());
  113. }
  114. //检查备份目录是否可写
  115. if (!is_writeable($config['path'])) {
  116. return ['status' => 0, 'info' => '备份目录不存在或不可写,请检查后重试!'];
  117. }
  118. \Yii::$app->session->set('backup_config', $config);
  119. //生成备份文件信息
  120. $file = array(
  121. 'name' => date('Ymd-His', time()),
  122. 'part' => 1,
  123. );
  124. \Yii::$app->session->set('backup_file', $file);
  125. //缓存要备份的表
  126. \Yii::$app->session->set('backup_tables', $tables);
  127. //创建备份文件
  128. $Database = new Database($file, $config);
  129. if(false !== $Database->create()){
  130. $tab = ['id' => 0, 'start' => 0];
  131. return [
  132. 'status' => 1,
  133. 'info' => '初始化成功!',
  134. 'tables' => $tables,
  135. 'tab' => $tab
  136. ];
  137. } else {
  138. return [
  139. 'status' => 0,
  140. 'info' => '初始化失败,备份文件创建失败!'
  141. ];
  142. }
  143. }
  144. public function actionStart($id = null, $start = null)
  145. {
  146. \Yii::$app->response->format = Response::FORMAT_JSON;
  147. $tables = \Yii::$app->session->get('backup_tables');
  148. $id = \Yii::$app->request->post('id');
  149. $start = \Yii::$app->request->post('start');
  150. //备份指定表
  151. $Database = new Database(\Yii::$app->session->get('backup_file'), \Yii::$app->session->get('backup_config'));
  152. $start = $Database->backup($tables[$id], $start);
  153. if(false === $start){ //出错
  154. return [
  155. 'status' => 0,
  156. 'info' => '备份出错!'
  157. ];
  158. } elseif (0 === $start) { //下一表
  159. if(isset($tables[++$id])){
  160. $tab = array('id' => $id, 'start' => 0);
  161. return [
  162. 'status' => 1,
  163. 'tab' => $tab
  164. ];
  165. } else { //备份完成,清空缓存
  166. unlink(\Yii::$app->session->get('backup_config')['path'] . 'backup.lock');
  167. \Yii::$app->session->set('backup_tables', null);
  168. \Yii::$app->session->set('backup_file', null);
  169. \Yii::$app->session->set('backup_config', null);
  170. return [
  171. 'status' => 1,
  172. 'info' => '备份完成!'
  173. ];
  174. }
  175. } else {
  176. $tab = array('id' => $id, 'start' => $start[0]);
  177. $rate = floor(100 * ($start[0] / $start[1]));
  178. return [
  179. 'status' => 1,
  180. 'info' => "正在备份...({$rate}%)",
  181. 'tab' => $tab
  182. ];
  183. }
  184. }
  185. }