model.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. <?php
  2. /** 安装界面需要的各种模块 */
  3. class installModel
  4. {
  5. private $host;
  6. private $name;
  7. private $user;
  8. private $encoding;
  9. private $password;
  10. private $port;
  11. private $prefix;
  12. private $successTable = [];
  13. /**
  14. * @var bool
  15. */
  16. private $allowNext = true;
  17. /**
  18. * @var PDO|string
  19. */
  20. private $dbh = null;
  21. /**
  22. * @var bool
  23. */
  24. private $clearDB = false;
  25. /**
  26. * Notes: php版本
  27. * @author luzg(2020/8/25 9:56)
  28. * @return string
  29. */
  30. public function getPhpVersion()
  31. {
  32. return PHP_VERSION;
  33. }
  34. /**
  35. * Notes: 当前版本是否符合
  36. * @author luzg(2020/8/25 9:57)
  37. * @return string
  38. */
  39. public function checkPHP()
  40. {
  41. return $result = version_compare(PHP_VERSION, '7.2.0') >= 0 ? 'ok' : 'fail';
  42. }
  43. /**
  44. * Notes: 是否有PDO
  45. * @author luzg(2020/8/25 9:57)
  46. * @return string
  47. */
  48. public function checkPDO()
  49. {
  50. return $result = extension_loaded('pdo') ? 'ok' : 'fail';
  51. }
  52. /**
  53. * Notes: 是否有PDO::MySQL
  54. * @author luzg(2020/8/25 9:58)
  55. * @return string
  56. */
  57. public function checkPDOMySQL()
  58. {
  59. return $result = extension_loaded('pdo_mysql') ? 'ok' : 'fail';
  60. }
  61. /**
  62. * Notes: 是否支持JSON
  63. * @author luzg(2020/8/25 9:58)
  64. * @return string
  65. */
  66. public function checkJSON()
  67. {
  68. return $result = extension_loaded('json') ? 'ok' : 'fail';
  69. }
  70. /**
  71. * Notes: 是否支持openssl
  72. * @author luzg(2020/8/25 9:58)
  73. * @return string
  74. */
  75. public function checkOpenssl()
  76. {
  77. return $result = extension_loaded('openssl') ? 'ok' : 'fail';
  78. }
  79. /**
  80. * Notes: 是否支持mbstring
  81. * @author luzg(2020/8/25 9:58)
  82. * @return string
  83. */
  84. public function checkMbstring()
  85. {
  86. return $result = extension_loaded('mbstring') ? 'ok' : 'fail';
  87. }
  88. /**
  89. * Notes: 是否支持zlib
  90. * @author luzg(2020/8/25 9:59)
  91. * @return string
  92. */
  93. public function checkZlib()
  94. {
  95. return $result = extension_loaded('zlib') ? 'ok' : 'fail';
  96. }
  97. /**
  98. * Notes: 是否支持curl
  99. * @author luzg(2020/8/25 9:59)
  100. * @return string
  101. */
  102. public function checkCurl()
  103. {
  104. return $result = extension_loaded('curl') ? 'ok' : 'fail';
  105. }
  106. /**
  107. * Notes: 检查GD2扩展
  108. * @author luzg(2020/8/26 9:59)
  109. * @return string
  110. */
  111. public function checkGd2()
  112. {
  113. return $result = extension_loaded('gd') ? 'ok' : 'fail';
  114. }
  115. /**
  116. * Notes: 检查Dom扩展
  117. * @author luzg(2020/8/26 9:59)
  118. * @return string
  119. */
  120. public function checkDom()
  121. {
  122. return $result = extension_loaded('dom') ? 'ok' : 'fail';
  123. }
  124. /**
  125. * Notes: 是否支持filter
  126. * @author luzg(2020/8/25 9:59)
  127. * @return string
  128. */
  129. public function checkFilter()
  130. {
  131. return $result = extension_loaded('filter') ? 'ok' : 'fail';
  132. }
  133. /**
  134. * Notes: 是否支持iconv
  135. * @author luzg(2020/8/25 9:59)
  136. * @return string
  137. */
  138. public function checkIconv()
  139. {
  140. return $result = extension_loaded('iconv') ? 'ok' : 'fail';
  141. }
  142. /**
  143. * Notes: 检查fileinfo扩展
  144. * @author 段誉(2021/6/28 11:03)
  145. * @return string
  146. */
  147. public function checkFileInfo()
  148. {
  149. return $result = extension_loaded('fileinfo') ? 'ok' : 'fail';
  150. }
  151. /**
  152. * Notes: SESSION路径是否可写
  153. * @author luzg(2020/8/25 10:06)
  154. * @return mixed
  155. */
  156. public function getSessionSavePath()
  157. {
  158. $sessionSavePath = preg_replace("/\d;/", '', session_save_path());
  159. return [
  160. 'path' => $sessionSavePath,
  161. 'exists' => is_dir($sessionSavePath),
  162. 'writable' => is_writable($sessionSavePath),
  163. ];
  164. }
  165. /**
  166. * Notes: 检查session路径可写状态
  167. * @author luzg(2020/8/25 10:13)
  168. * @return string
  169. */
  170. public function checkSessionSavePath()
  171. {
  172. $sessionSavePath = preg_replace("/\d;/", '', session_save_path());
  173. $result = (is_dir($sessionSavePath) and is_writable($sessionSavePath)) ? 'ok' : 'fail';
  174. if ($result == 'fail') return $result;
  175. file_put_contents($sessionSavePath . '/zentaotest', 'zentao');
  176. $sessionContent = file_get_contents($sessionSavePath . '/zentaotest');
  177. if ($sessionContent == 'zentao') {
  178. unlink($sessionSavePath . '/zentaotest');
  179. return 'ok';
  180. }
  181. return 'fail';
  182. }
  183. /**
  184. * Notes: 取得php.ini信息
  185. * @author luzg(2020/8/25 11:03)
  186. * @return string
  187. */
  188. public function getIniInfo()
  189. {
  190. $iniInfo = '';
  191. ob_start();
  192. phpinfo(1);
  193. $lines = explode("\n", strip_tags(ob_get_contents()));
  194. ob_end_clean();
  195. foreach ($lines as $line) if (strpos($line, 'ini') !== false) $iniInfo .= $line . "\n";
  196. return $iniInfo;
  197. }
  198. public function mkdataconfig($db)
  199. {
  200. $config = include $this->getInstallRoot() . '/data/example.php';
  201. $config = str_replace(array(
  202. '{db-server}', '{db-username}', '{db-password}', '{db-port}', '{db-name}', '{db-tablepre}'
  203. ), array(
  204. $db['server'], $db['username'], $db['password'], $db['port'], $db['name'], $db['prefix']
  205. ), $config);
  206. return file_put_contents($this->getInstallRoot() . '/data/config.php', $config);
  207. }
  208. /**
  209. * Notes: 创建安装锁定文件
  210. * @author luzg(2020/8/28 11:32)
  211. * @return bool
  212. */
  213. public function mkLockFile()
  214. {
  215. return touch($this->getInstallRoot() . '/data/install.lock');
  216. }
  217. /**
  218. * Notes: 检查之前是否有安装
  219. * @author luzg(2020/8/28 11:36)
  220. */
  221. public function appIsInstalled()
  222. {
  223. return file_exists($this->getInstallRoot() . '/data/install.lock');
  224. }
  225. /**
  226. * Notes: 取得配置信息
  227. * @author luzg(2020/8/25 11:05)
  228. * @param string $dbName 数据库名称
  229. * @param array $connectionInfo 连接信息
  230. * @return stdclass
  231. * @throws Exception
  232. */
  233. public function checkConfig($dbName, $connectionInfo)
  234. {
  235. $return = new stdclass();
  236. $return->result = 'ok';
  237. /* Connect to database. */
  238. $this->setDBParam($connectionInfo);
  239. $this->dbh = $this->connectDB();
  240. if (strpos($dbName, '.') !== false) {
  241. $return->result = 'fail';
  242. $return->error = '没有发现数据库信息';
  243. return $return;
  244. }
  245. if (!is_object($this->dbh)) {
  246. $return->result = 'fail';
  247. $return->error = '安装错误,请检查连接信息:' . mb_strcut($this->dbh, 0, 30) . '...';
  248. echo $this->dbh;
  249. return $return;
  250. }
  251. /* Get mysql version. */
  252. $version = $this->getMysqlVersion();
  253. /* check mysql sql_model */
  254. // if(!$this->checkSqlMode($version)) {
  255. // $return->result = 'fail';
  256. // $return->error = '请在mysql配置文件修改sql-mode添加NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
  257. // return $return;
  258. // }
  259. /* If database no exits, try create it. */
  260. if (!$this->dbExists()) {
  261. if (!$this->createDB($version)) {
  262. $return->result = 'fail';
  263. $return->error = '创建数据库错误';
  264. return $return;
  265. }
  266. } elseif ($this->tableExits() and $this->clearDB == false) {
  267. $return->result = 'fail';
  268. $return->error = '数据表已存在,您之前可能已安装本系统,如需继续安装请选择新的数据库。';
  269. return $return;
  270. } elseif ($this->dbExists() and $this->clearDB == true) {
  271. if (!$this->dropDb($connectionInfo['name'])) {
  272. $return->result = 'fail';
  273. $return->error = '数据表已经存在,删除已存在库错误,请手动清除';
  274. return $return;
  275. } else {
  276. if (!$this->createDB($version)) {
  277. $return->result = 'fail';
  278. $return->error = '创建数据库错误!';
  279. return $return;
  280. }
  281. }
  282. }
  283. /* Create tables. */
  284. if (!$this->createTable($version, $connectionInfo)) {
  285. $return->result = 'fail';
  286. $return->error = '创建表格失败';
  287. return $return;
  288. }
  289. return $return;
  290. }
  291. /**
  292. * Notes: 设置数据库相关信息
  293. * @author luzg(2020/8/25 11:17)
  294. * @param $post
  295. */
  296. public function setDBParam($post)
  297. {
  298. $this->host = $post['host'];
  299. $this->name = $post['name'];
  300. $this->user = $post['user'];
  301. $this->encoding = 'utf8mb4';
  302. $this->password = $post['password'];
  303. $this->port = $post['port'];
  304. $this->prefix = $post['prefix'];
  305. $this->clearDB = $post['clear_db'] == 'on';
  306. }
  307. /**
  308. * Notes: 连接数据库
  309. * @author luzg(2020/8/25 11:56)
  310. * @return PDO|string
  311. */
  312. public function connectDB()
  313. {
  314. $dsn = "mysql:host={$this->host}; port={$this->port};charset=utf8";
  315. //$dsn = "mysql:dbname=echarts;host=localhost;port:3306;charset=utf8";
  316. try {
  317. $dbh = new PDO($dsn, $this->user, $this->password);
  318. $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
  319. $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  320. $dbh->exec("SET NAMES {$this->encoding}");
  321. $dbh->exec("SET NAMES {$this->encoding}");
  322. try {
  323. $dbh->exec("SET GLOBAL sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';");
  324. } catch (Exception $e) {
  325. }
  326. return $dbh;
  327. } catch (PDOException $exception) {
  328. return $exception->getMessage();
  329. }
  330. }
  331. /**
  332. * Notes: 检查数据库是否存在
  333. * @author luzg(2020/8/25 11:56)
  334. * @return mixed
  335. */
  336. public function dbExists()
  337. {
  338. $sql = "SHOW DATABASES like '{$this->name}'";
  339. return $this->dbh->query($sql)->fetch();
  340. }
  341. /**
  342. * Notes: 检查表是否存在
  343. * @author luzg(2020/8/25 11:56)
  344. * @return mixed
  345. */
  346. public function tableExits()
  347. {
  348. $configTable = sprintf("'%s'", $this->prefix . TESTING_TABLE);
  349. $sql = "SHOW TABLES FROM {$this->name} like $configTable";
  350. return $this->dbh->query($sql)->fetch();
  351. }
  352. /**
  353. * Notes: 获取mysql版本号
  354. * @author luzg(2020/8/25 11:56)
  355. * @return false|string
  356. */
  357. public function getMysqlVersion()
  358. {
  359. $sql = "SELECT VERSION() AS version";
  360. $result = $this->dbh->query($sql)->fetch();
  361. return substr($result->version, 0, 3);
  362. }
  363. /**
  364. * @notes 检测数据库sql_mode
  365. * @param $version
  366. * @return bool
  367. * @author 段誉
  368. * @date 2021/8/27 17:17
  369. */
  370. public function checkSqlMode($version)
  371. {
  372. $sql = "SELECT @@global.sql_mode";
  373. $result = $this->dbh->query($sql)->fetch();
  374. $result = (array)$result;
  375. if ($version >= 5.7 && $version < 8.0) {
  376. if ((strpos($result['@@global.sql_mode'], 'NO_AUTO_CREATE_USER') !== false)
  377. && (strpos($result['@@global.sql_mode'], 'NO_ENGINE_SUBSTITUTION') !== false)
  378. ) {
  379. return true;
  380. }
  381. return false;
  382. }
  383. return true;
  384. }
  385. /**
  386. * Notes: 创建数据库
  387. * @author luzg(2020/8/25 11:57)
  388. * @param $version
  389. * @return mixed
  390. */
  391. public function createDB($version)
  392. {
  393. $sql = "CREATE DATABASE `{$this->name}`";
  394. if ($version > 4.1) $sql .= " DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci";
  395. return $this->dbh->query($sql);
  396. }
  397. /**
  398. * Notes: 创建表
  399. * @author luzg(2020/8/25 11:57)
  400. * @param $version
  401. * @param $post
  402. * @return bool
  403. * @throws Exception
  404. */
  405. public function createTable($version, $post)
  406. {
  407. $dbFile = $this->getInstallRoot() . '/data/installdata.sql';
  408. //file_put_contents($dbFile, $this->initAccount($post), FILE_APPEND);
  409. $content = str_replace(";\r\n", ";\n", file_get_contents($dbFile));
  410. $tables = explode(";\n", $content);
  411. $tables[] = $this->initAccount($post);
  412. $installTime = microtime(true) * 10000;
  413. foreach ($tables as $table) {
  414. $table = trim($table);
  415. if (empty($table)) continue;
  416. if (strpos($table, 'CREATE') !== false and $version <= 4.1) {
  417. $table = str_replace('DEFAULT CHARSET=utf8', '', $table);
  418. }
  419. // elseif (strpos($table, 'DROP') !== false and $this->clearDB != false) {
  420. // $table = str_replace('--', '', $table);
  421. // }
  422. /* Skip sql that is note. */
  423. if (strpos($table, '--') === 0) continue;
  424. $table = str_replace('`ims_', $this->name . '.`ims_', $table);
  425. $table = str_replace('`ims_', '`' . $this->prefix, $table);
  426. if (strpos($table, 'CREATE') !== false) {
  427. $tableName = explode('`', $table)[1];
  428. $installTime += random_int(3000, 7000);
  429. $this->successTable[] = [$tableName, date('Y-m-d H:i:s', $installTime / 10000)];
  430. }
  431. // if (strpos($table, "INSERT INTO ") !== false) {
  432. // $table = str_replace('INSERT INTO ', 'INSERT INTO ' .$this->name .'.', $table);
  433. // }
  434. try {
  435. if (!$this->dbh->query($table)) return false;
  436. } catch (Exception $e) {
  437. echo 'error sql: ' . $table . "<br>";
  438. echo $e->getMessage() . "<br>";
  439. return false;
  440. }
  441. }
  442. return true;
  443. }
  444. /**
  445. * Notes: 删除数据库
  446. * @param $db
  447. * @return false|PDOStatement
  448. */
  449. public function dropDb($db)
  450. {
  451. $sql = "drop database {$db};";
  452. return $this->dbh->query($sql);
  453. }
  454. /**
  455. * Notes: 取得安装成功的表列表
  456. * @author luzg(2020/8/26 18:28)
  457. * @return array
  458. */
  459. public function getSuccessTable()
  460. {
  461. return $this->successTable;
  462. }
  463. /**
  464. * Notes: 创建演示数据
  465. * @author luzg(2020/8/25 11:58)
  466. * @return bool
  467. */
  468. public function importDemoData()
  469. {
  470. $demoDataFile = 'ys.sql';
  471. $demoDataFile = $this->getInstallRoot() . '/data/' . $demoDataFile;
  472. if (!is_file($demoDataFile)) {
  473. echo "<br>";
  474. echo 'no file:' . $demoDataFile;
  475. return false;
  476. }
  477. $content = str_replace(";\r\n", ";\n", file_get_contents($demoDataFile));
  478. $insertTables = explode(";\n", $content);
  479. foreach ($insertTables as $table) {
  480. $table = trim($table);
  481. if (empty($table)) continue;
  482. $table = str_replace('`ims_', $this->name . '.`ims_', $table);
  483. $table = str_replace('`ims_', '`' . $this->prefix, $table);
  484. if (!$this->dbh->query($table)) return false;
  485. }
  486. // 移动图片资源
  487. $this->cpFiles($this->getInstallRoot() . '/uploads', $this->getAppRoot() . '/public/uploads');
  488. return true;
  489. }
  490. /**
  491. * 将一个文件夹下的所有文件及文件夹
  492. * 复制到另一个文件夹里(保持原有结构)
  493. *
  494. * @param <string> $rootFrom 源文件夹地址(最好为绝对路径)
  495. * @param <string> $rootTo 目的文件夹地址(最好为绝对路径)
  496. */
  497. function cpFiles($rootFrom, $rootTo)
  498. {
  499. $handle = opendir($rootFrom);
  500. while (false !== ($file = readdir($handle))) {
  501. //DIRECTORY_SEPARATOR 为系统的文件夹名称的分隔符 例如:windos为'/'; linux为'/'
  502. $fileFrom = $rootFrom . DIRECTORY_SEPARATOR . $file;
  503. $fileTo = $rootTo . DIRECTORY_SEPARATOR . $file;
  504. if ($file == '.' || $file == '..') {
  505. continue;
  506. }
  507. if (is_dir($fileFrom)) {
  508. if (!is_dir($fileTo)) { //目标目录不存在则创建
  509. mkdir($fileTo, 0777);
  510. }
  511. $this->cpFiles($fileFrom, $fileTo);
  512. } else {
  513. if (!file_exists($fileTo)) {
  514. @copy($fileFrom, $fileTo);
  515. if (strstr($fileTo, "access_token.txt")) {
  516. chmod($fileTo, 0777);
  517. }
  518. }
  519. }
  520. }
  521. }
  522. /**
  523. * Notes: 当前应用程序的相对路径
  524. * @author luzg(2020/8/25 10:55)
  525. * @return string
  526. */
  527. public function getAppRoot()
  528. {
  529. return dirname(dirname(INSTALL_ROOT));
  530. }
  531. /**
  532. * Notes: 获取安装目录
  533. * @author luzg(2020/8/26 16:15)
  534. * @return string
  535. */
  536. public function getInstallRoot()
  537. {
  538. return dirname(dirname(INSTALL_ROOT));
  539. }
  540. /**
  541. * Notes: 目录的容量
  542. * @author luzg(2020/8/25 15:21)
  543. * @param $dir
  544. * @return string
  545. */
  546. public function freeDiskSpace($dir)
  547. {
  548. // M
  549. $freeDiskSpace = disk_free_space(realpath(__DIR__)) / 1024 / 1024;
  550. // G
  551. if ($freeDiskSpace > 1024) {
  552. return number_format($freeDiskSpace / 1024, 2) . 'G';
  553. }
  554. return number_format($freeDiskSpace, 2) . 'M';
  555. }
  556. /**
  557. * Notes: 获取状态标志
  558. * @author luzg(2020/8/25 16:10)
  559. * @param $statusSingle
  560. * @return string
  561. */
  562. public function correctOrFail($statusSingle)
  563. {
  564. if ($statusSingle == 'ok')
  565. return '<td class="layui-icon green">&#xe605;</td>';
  566. $this->allowNext = false;
  567. return '<td class="layui-icon wrong">&#x1006;</td>';
  568. }
  569. /**
  570. * Notes: 是否允许下一步
  571. * @author luzg(2020/8/25 17:29)
  572. * @return bool
  573. */
  574. public function getAllowNext()
  575. {
  576. return $this->allowNext;
  577. }
  578. public function checkSessionAutoStart()
  579. {
  580. return $result = ini_get('session.auto_start') == '0' ? 'ok' : 'fail';
  581. }
  582. public function checkAutoTags()
  583. {
  584. return $result = ini_get('session.auto_start') == '0' ? 'ok' : 'fail';
  585. }
  586. /**
  587. * Notes: 检查目录是否可写
  588. * @param $dir
  589. * @return string
  590. */
  591. public function checkDirWrite($dir = '')
  592. {
  593. $route = $this->getAppRoot() . '/' . $dir;
  594. return $result = is_writable($route) ? 'ok' : 'fail';
  595. }
  596. public function checkInstallRootDirWrite($dir = '')
  597. {
  598. $route = $this->getInstallRoot() . '/' . $dir;
  599. return $result = is_writable($route) ? 'ok' : 'fail';
  600. }
  601. /**
  602. * Notes: 初始化管理账号
  603. * @param $post
  604. * @return string
  605. */
  606. public function initAccount($post)
  607. {
  608. $time = time();
  609. $salt = substr(md5($time . $post['admin_user']), 0, 8); //随机4位密码盐
  610. global $uniqueSalt;
  611. $uniqueSalt = $salt;
  612. $password = $this->createPassword($post['admin_password'], $salt);
  613. // 超级管理员
  614. $sql = "INSERT INTO `ims_xm_mallv3_user` (`id`, `uuid`, `weid`, `lastweid`, `uid`, `w7uid`, `did`, `sid`, `username`, `password`, `salt`, `touxiang`, `qianming`, `title`, `sex`, `mobile`, `role_id`, `remark`, `px`, `time`, `role`, `create_time`, `update_time`, `status`) VALUES
  615. (1, NULL, 0, 0, NULL, 1, NULL, 0, '{$post['admin_user']}', '{$password}', '{$salt}', '', '', '{$post['admin_user']}', 0, NULL, 0, '', 0, 0, NULL, 0, {$time}, 1);";
  616. return $sql;
  617. }
  618. /**
  619. * Notes: 生成密码密文
  620. * @param $pwd
  621. * @param $salt
  622. * @return string
  623. */
  624. function createPassword($passwordinput, $salt)
  625. {
  626. $myconfig = include $this->getAppRoot() . '/config/my.php';
  627. $authkey = $myconfig['authkey'];
  628. $passwordinput = "{$passwordinput}-{$salt}-{$authkey}";
  629. return sha1($passwordinput);
  630. }
  631. public function restoreIndexLock()
  632. {
  633. $this->checkIndexFile($this->getAppRoot() . '/admin');
  634. }
  635. public function checkIndexFile($path)
  636. {
  637. if (file_exists($path . '/index_lock.html')) {
  638. // 删除提示文件
  639. unlink($path . '/index.html');
  640. // 恢复原入口
  641. rename($path . '/index_lock.html', $path . '/index.html');
  642. }
  643. }
  644. }