国内流行的内容管理系统(CMS)多端全媒体解决方案 https://www.dedebiz.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
10KB

  1. <?php
  2. /**
  3. * 数据库备份还原操作
  4. *
  5. * @version $id:sys_data_done.php 17:19 2010年7月20日 tianya $
  6. * @package DedeBIZ.Administrator
  7. * @copyright Copyright (c) 2022 DedeBIZ.COM
  8. * @license https://www.dedebiz.com/license
  9. * @link https://www.dedebiz.com
  10. */
  11. @ob_start();
  12. @set_time_limit(0);
  13. ini_set('memory_limit', '-1');
  14. require_once(dirname(__FILE__).'/config.php');
  15. if (DEDEBIZ_SAFE_MODE) {
  16. die(DedeAlert("系统已启用安全模式,无法使用当前功能",ALERT_DANGER));
  17. }
  18. CheckPurview('sys_Data');
  19. if (empty($dopost)) $dopost = '';
  20. $bkdir = DEDEDATA.'/'.$cfg_backup_dir;
  21. //跳转一下页的js
  22. $gotojs = "function GotoNextPage(){document.gonext."."submit();}"."\r\nset"."Timeout('GotoNextPage()',500);";
  23. $dojs = "<script>$gotojs</script>";
  24. //备份数据
  25. if ($dopost == 'bak') {
  26. if (empty($tablearr)) {
  27. ShowMsg('您还没选择备份数据表', 'javascript:;');
  28. exit();
  29. }
  30. if (!is_dir($bkdir)) {
  31. MkdirAll($bkdir, $cfg_dir_purview);
  32. CloseFtp();
  33. }
  34. //初始化使用到的变量
  35. $tables = explode(',', $tablearr);
  36. if (!isset($isstruct)) {
  37. $isstruct = 0;
  38. }
  39. if (!isset($startpos)) {
  40. $startpos = 0;
  41. }
  42. if (!isset($iszip)) {
  43. $iszip = 0;
  44. }
  45. if (empty($nowtable)) {
  46. $nowtable = '';
  47. }
  48. if (empty($fsize)) {
  49. $fsize = 2048;
  50. }
  51. $fsizeb = $fsize * 1024;
  52. //第一页的操作
  53. if ($nowtable == '') {
  54. $tmsg = '';
  55. $dh = dir($bkdir);
  56. while ($filename = $dh->read()) {
  57. if (!preg_match("#txt$#", $filename)) {
  58. continue;
  59. }
  60. $filename = $bkdir."/$filename";
  61. if (!is_dir($filename)) {
  62. unlink($filename);
  63. }
  64. }
  65. $dh->close();
  66. $tmsg .= "完成备份目录旧数据清理";
  67. if ($isstruct == 1) {
  68. $bkfile = $bkdir."/tables_struct_".substr(md5(time().mt_rand(1000, 5000).$cfg_cookie_encode), 0, 16).".txt";
  69. $mysql_version = $dsql->GetVersion();
  70. $fp = fopen($bkfile, "w");
  71. foreach ($tables as $t) {
  72. fwrite($fp, "DROP TABLE IF EXISTS `$t`;\r\n\r\n");
  73. $dsql->SetQuery("SHOW CREATE TABLE ".$dsql->dbName.".".$t);
  74. $dsql->Execute('me');
  75. $row = $dsql->GetArray('me', MYSQL_BOTH);
  76. //去除AUTO_INCREMENT
  77. $row[1] = preg_replace("#AUTO_INCREMENT=([0-9]{1,})[ \r\n\t]{1,}#i", "", $row[1]);
  78. $eng1 = "#ENGINE=MyISAM[ \r\n\t]{1,}DEFAULT[ \r\n\t]{1,}CHARSET=".$cfg_db_language."#i";
  79. $tableStruct = preg_replace($eng1, "TYPE=MyISAM", $row[1]);
  80. fwrite($fp, ''.$tableStruct.";\r\n\r\n");
  81. }
  82. fclose($fp);
  83. $tmsg .= "完成备份数据表结构信息";
  84. }
  85. $tmsg .= "正在进行数据备份初始化工作,请稍后";
  86. $doneForm = "<form name='gonext' method='post' action='sys_data_done.php'>
  87. <input type='hidden' name='isstruct' value='$isstruct'>
  88. <input type='hidden' name='dopost' value='bak'>
  89. <input type='hidden' name='fsize' value='$fsize'>
  90. <input type='hidden' name='tablearr' value='$tablearr'>
  91. <input type='hidden' name='nowtable' value='{$tables[0]}'>
  92. <input type='hidden' name='startpos' value='0'>
  93. <input type='hidden' name='iszip' value='$iszip'>\r\n</form>\r\n{$dojs}\r\n";
  94. PutInfo($tmsg, $doneForm);
  95. exit();
  96. }
  97. //执行分页备份
  98. else {
  99. $j = 0;
  100. $fs = array();
  101. $bakStr = '';
  102. //分析表里的字段信息
  103. $nowtable = str_replace("`", "", $nowtable);
  104. if (!$dsql->IsTable($nowtable)) {
  105. PutInfo("数据表名称错误", "");
  106. exit();
  107. }
  108. $dsql->GetTableFields($nowtable);
  109. $intable = "INSERT INTO `$nowtable` VALUES(";
  110. while ($r = $dsql->GetFieldObject()) {
  111. $fs[$j] = trim($r->name);
  112. $j++;
  113. }
  114. $fsd = $j - 1;
  115. //读取表的文档
  116. $dsql->SetQuery("SELECT * FROM `$nowtable`");
  117. $dsql->Execute();
  118. $m = 0;
  119. $bakfilename = "$bkdir/{$nowtable}_{$startpos}_".substr(md5(time().mt_rand(1000, 5000).$cfg_cookie_encode), 0, 16).".txt";
  120. while ($row2 = $dsql->GetArray()) {
  121. if ($m < $startpos) {
  122. $m++;
  123. continue;
  124. }
  125. //检测数据是否达到规定大小
  126. if (strlen($bakStr) > $fsizeb) {
  127. $fp = fopen($bakfilename, "w");
  128. fwrite($fp, $bakStr);
  129. fclose($fp);
  130. $tmsg = "正在备份{$m}条数据,继续备份{$nowtable}";
  131. $doneForm = "<form name='gonext' method='post' action='sys_data_done.php'>
  132. <input type='hidden' name='isstruct' value='$isstruct'>
  133. <input type='hidden' name='dopost' value='bak'>
  134. <input type='hidden' name='fsize' value='$fsize'>
  135. <input type='hidden' name='tablearr' value='$tablearr'>
  136. <input type='hidden' name='nowtable' value='$nowtable'>
  137. <input type='hidden' name='startpos' value='$m'>
  138. <input type='hidden' name='iszip' value='$iszip'>\r\n</form>\r\n{$dojs}\r\n";
  139. PutInfo($tmsg, $doneForm);
  140. exit();
  141. }
  142. //正常情况
  143. $line = $intable;
  144. for ($j = 0; $j <= $fsd; $j++) {
  145. if ($j < $fsd) {
  146. $line .= "'".RpLine(addslashes($row2[$fs[$j]]))."',";
  147. } else {
  148. $line .= "'".RpLine(addslashes($row2[$fs[$j]]))."');\r\n";
  149. }
  150. }
  151. $m++;
  152. $bakStr .= $line;
  153. }
  154. //如果数据比卷设置值小
  155. if ($bakStr != '') {
  156. $fp = fopen($bakfilename, "w");
  157. fwrite($fp, $bakStr);
  158. fclose($fp);
  159. }
  160. for ($i = 0; $i < count($tables); $i++) {
  161. if ($tables[$i] == $nowtable) {
  162. if (isset($tables[$i + 1])) {
  163. $nowtable = $tables[$i + 1];
  164. $startpos = 0;
  165. break;
  166. } else {
  167. PutInfo("成功完成所有数据备份", "");
  168. exit();
  169. }
  170. }
  171. }
  172. $tmsg = "正在备份{$m}条数据,继续备份{$nowtable}";
  173. $doneForm = "<form name='gonext' method='post' action='sys_data_done.php?dopost=bak'>
  174. <input type='hidden' name='isstruct' value='$isstruct'>
  175. <input type='hidden' name='fsize' value='$fsize'>
  176. <input type='hidden' name='tablearr' value='$tablearr'>
  177. <input type='hidden' name='nowtable' value='$nowtable'>
  178. <input type='hidden' name='startpos' value='$startpos'>\r\n</form>\r\n{$dojs}\r\n";
  179. PutInfo($tmsg, $doneForm);
  180. exit();
  181. }
  182. //分页备份代码结束
  183. }
  184. //还原数据
  185. else if ($dopost == 'redat') {
  186. if ($bakfiles == '') {
  187. ShowMsg('您还没选择还原数据表', 'javascript:;');
  188. exit();
  189. }
  190. $bakfilesTmp = $bakfiles;
  191. $bakfiles = explode(',', $bakfiles);
  192. if (empty($structfile)) {
  193. $structfile = "";
  194. }
  195. if (empty($delfile)) {
  196. $delfile = 0;
  197. }
  198. if (empty($startgo)) {
  199. $startgo = 0;
  200. }
  201. if ($startgo == 0 && $structfile != '') {
  202. $tbdata = '';
  203. $fp = fopen("$bkdir/$structfile", 'r');
  204. while (!feof($fp)) {
  205. $tbdata .= fgets($fp, 1024);
  206. }
  207. fclose($fp);
  208. $querys = explode(';', $tbdata);
  209. foreach ($querys as $q) {
  210. $q = preg_replace("#TYPE=MyISAM#i","ENGINE=MyISAM DEFAULT CHARSET=".$cfg_db_language, $q);
  211. $rs = $dsql->ExecuteNoneQuery(trim($q).';');
  212. }
  213. if ($delfile == 1) {
  214. @unlink("$bkdir/$structfile");
  215. }
  216. $tmsg = "成功完成数据表还原,继续还原其它数据";
  217. $doneForm = "<form name='gonext' method='post' action='sys_data_done.php?dopost=redat'>
  218. <input type='hidden' name='startgo' value='1'>
  219. <input type='hidden' name='delfile' value='$delfile'>
  220. <input type='hidden' name='bakfiles' value='$bakfilesTmp'>
  221. </form>\r\n{$dojs}\r\n";
  222. PutInfo($tmsg, $doneForm);
  223. exit();
  224. } else {
  225. $nowfile = $bakfiles[0];
  226. $bakfilesTmp = preg_replace("#".$nowfile."[,]{0,1}#", "", $bakfilesTmp);
  227. $oknum = 0;
  228. if (filesize("$bkdir/$nowfile") > 0) {
  229. $fp = fopen("$bkdir/$nowfile", 'r');
  230. while (!feof($fp)) {
  231. $line = trim(fgets($fp, 512 * 1024));
  232. if ($line == "") continue;
  233. $rs = $dsql->ExecuteNoneQuery($line);
  234. if ($rs) $oknum++;
  235. }
  236. fclose($fp);
  237. }
  238. if ($delfile == 1) {
  239. @unlink("$bkdir/$nowfile");
  240. }
  241. if ($bakfilesTmp == "") {
  242. ShowMsg('成功还原所有数据', 'javascript:;');
  243. exit();
  244. }
  245. $tmsg = "正在还原{$nowfile}文件{$oknum}条数据,继续还原其它数据";
  246. $doneForm = "<form name='gonext' method='post' action='sys_data_done.php?dopost=redat'>
  247. <input type='hidden' name='startgo' value='1'>
  248. <input type='hidden' name='delfile' value='$delfile'>
  249. <input type='hidden' name='bakfiles' value='$bakfilesTmp'>
  250. </form>\r\n{$dojs}\r\n";
  251. PutInfo($tmsg, $doneForm);
  252. exit();
  253. }
  254. }
  255. function PutInfo($msg1, $msg2)
  256. {
  257. global $cfg_soft_lang;
  258. $msginfo = "<!DOCTYPE html><html><head><meta charset='utf-8'><meta http-equiv='X-UA-Compatible' content='IE=Edge,chrome=1'><meta name='viewport' content='width=device-width,initial-scale=1'><title>系统提示</title><link rel='stylesheet' href='/static/web/css/bootstrap.min.css'><link rel='stylesheet' href='/static/web/css/admin.css'></head><base target='_self'><body class='body-bg'><div class='tips'><div class='tips-box'><div class='tips-head'><p>系统提示</p></div><div class='tips-body'>{$msg1}{$msg2}</div></div></div>";
  259. echo $msginfo."</body></html>";
  260. }
  261. function RpLine($str)
  262. {
  263. $str = str_replace("\r", "\\r", $str);
  264. $str = str_replace("\n", "\\n", $str);
  265. return $str;
  266. }
  267. ?>