Upgrade2.php 5.5 KB

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