Upgrade2.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <?php
  2. ini_set('max_execution_time', 0);
  3. class Upgrade2
  4. {
  5. protected string $archiveFile = "";//升级文件地址
  6. protected string $extractPath = "";//解压目录地址
  7. protected string $root_path = "";//程序根目录
  8. public string $update_download_url = "";//升级zip文件下载地址
  9. public string $update_sql_url = "";//升级sql脚本文件地址
  10. public string $update_script = "";//升级后执行的脚本地址
  11. //构造方法初始化一些数据
  12. function __construct($update_download_url = null, $update_sql_url = null, $update_script = null)
  13. {
  14. $this->archiveFile = runtime_path() . 'mtab.zip';
  15. $this->extractPath = runtime_path();
  16. $this->root_path = root_path();
  17. if ($update_download_url !== null) {
  18. $this->update_download_url = $update_download_url;
  19. }
  20. if ($update_sql_url !== null) {
  21. $this->update_sql_url = $update_sql_url;
  22. }
  23. if ($update_script !== null) {
  24. $this->update_script = $update_script;
  25. }
  26. }
  27. //运行入口
  28. function run()
  29. {
  30. return $this->startUpgrade();
  31. }
  32. //新的进程启动升级
  33. private function startUpgrade()
  34. {
  35. //如果有程序代码的更新资源则更新程序代码
  36. if (strlen($this->update_download_url) > 1) {
  37. //如果有遗留的解压资源则删除
  38. $this->deleteDirectory("{$this->extractPath}mtab");
  39. //如果存在旧的升级包则删除
  40. $this->delZip();
  41. //下载远程更新包
  42. if(!$this->fileDownload()){
  43. return "资源下载失败";
  44. }
  45. //解压升级包
  46. if (!$this->unzip($this->archiveFile, $this->extractPath)) {
  47. $this->delZip();
  48. return '升级资源包解压失败';
  49. }
  50. //拷贝覆盖
  51. $this->copy();
  52. //删除下载的更新包
  53. $this->delZip();
  54. //更新完后的一些操作
  55. }
  56. //如果有数据库的更新资源则更新程序代码
  57. if (strlen($this->update_sql_url) > 1) {
  58. $this->updateSql();
  59. }
  60. //退出
  61. return true;
  62. }
  63. private function fileDownload(): bool
  64. {
  65. try {
  66. $f = fopen($this->update_download_url, 'r');
  67. $w = fopen($this->archiveFile, 'wb+');
  68. do {
  69. $a = fread($f, 1024);
  70. fwrite($w, $a);
  71. } while ($a);
  72. fclose($w);
  73. fclose($f);
  74. } catch (ErrorException $e) {
  75. return false;
  76. }
  77. return true;
  78. }
  79. //删除升级包
  80. function delZip()
  81. {
  82. if (file_exists($this->archiveFile)) {
  83. unlink($this->archiveFile);
  84. }
  85. }
  86. //解压
  87. private function unzip($archiveFile, $extractPath): bool
  88. {
  89. $zip = new ZipArchive();
  90. if ($zip->open($archiveFile) === TRUE) {
  91. $zip->extractTo($extractPath, null);
  92. $zip->close();
  93. } else {
  94. return false;
  95. }
  96. return true;
  97. }
  98. //升级的数据库
  99. function updateSql()
  100. {
  101. $f = fopen($this->update_sql_url, 'r');
  102. $sql = "";
  103. do {
  104. $sqlTmp = fread($f, 1024);
  105. $sql = $sql . $sqlTmp;
  106. } while ($sqlTmp);
  107. fclose($f);
  108. // 解析SQL文件内容并执行
  109. $sql_statements = explode(';', trim($sql));
  110. foreach ($sql_statements as $sql_statement) {
  111. if (!empty($sql_statement)) {
  112. try {
  113. \think\facade\Db::query($sql_statement);
  114. } catch (Exception $e) {
  115. }
  116. }
  117. }
  118. }
  119. //递归删除目录
  120. function deleteDirectory($dir)
  121. {
  122. if (!is_dir($dir)) {
  123. return;
  124. }
  125. $files = scandir($dir);
  126. foreach ($files as $file) {
  127. if ($file != '.' && $file != '..') {
  128. if (is_dir("$dir/$file")) {
  129. $this->deleteDirectory("$dir/$file");
  130. } else {
  131. unlink("$dir/$file");
  132. }
  133. }
  134. }
  135. rmdir($dir);
  136. }
  137. // 递归复制目录及其内容
  138. function copyDir($source, $dest)
  139. {
  140. if (!is_dir($dest)) {
  141. mkdir($dest, 0777, true);
  142. }
  143. $files = scandir($source);
  144. foreach ($files as $file) {
  145. if ($file !== '.' && $file !== '..') {
  146. $src = $source . '/' . $file;
  147. $dst = $dest . '/' . $file;
  148. if (is_dir($src)) {
  149. $this->copyDir($src, $dst);
  150. } else {
  151. copy($src, $dst);
  152. }
  153. }
  154. }
  155. }
  156. //覆盖原来的程序
  157. private function copy()
  158. {
  159. //移动覆盖
  160. $this->copyDir("{$this->extractPath}mtab/", "{$this->root_path}");
  161. //删除解压目录
  162. $this->deleteDirectory("{$this->extractPath}mtab");
  163. }
  164. }