123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- <?php
- /**
- *ProxyPanel安装程序.
- *
- * 安装完成后建议删除此文件
- *
- * @author Heron
- */
- // error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
- // ini_set('display_errors', '1');
- define('DS', DIRECTORY_SEPARATOR); // 定义目录分隔符
- define('ROOT_PATH', __DIR__.DS.'..'.DS); // 定义根目录
- define('DB_PATH', ROOT_PATH.'sql'.DS.'db.sql'); // 数据库
- // 判断文件或目录是否有写的权限
- function is_really_writable($file)
- {
- if (DIRECTORY_SEPARATOR == '/' and @ini_get('safe_mode') == false) {
- return is_writable($file);
- }
- if (! is_file($file) or ($fp = @fopen($file, 'r+')) === false) {
- return false;
- }
- fclose($fp);
- return true;
- }
- $name = 'ProxyPanel';
- // 检测依赖组件目录是否存在
- $checkDirs = [
- 'vendor',
- ];
- // 错误信息
- $errInfo = '';
- // 数据库配置文件
- $ConfigFile = ROOT_PATH.'.env';
- // 数据库标准配置文件
- $exampleConfigFile = ROOT_PATH.'.env.example';
- // 锁定的文件
- $lockFile = ROOT_PATH.'.env';
- if (is_file($lockFile)) {
- $errInfo = '如果需要重新安装,请备份数据库后手动移除 .env 文件';
- } elseif (version_compare(PHP_VERSION, '7.3.0', '<')) {
- $errInfo = '当前PHP版本('.PHP_VERSION.')过低,请使用PHP7.3.0及以上版本';
- } elseif (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
- $errInfo = '当前系统环境为Windows,无法进行安装';
- } elseif (! is_file($exampleConfigFile)) {
- $errInfo = '缺失标准配置文件 .env.example';
- } elseif (! extension_loaded('PDO')) {
- $errInfo = '当前PHP环境未启用PDO组件,无法进行安装';
- } elseif (! is_really_writable(ROOT_PATH)) {
- $open_basedir = ini_get('open_basedir');
- if ($open_basedir) {
- $dirArr = explode(PATH_SEPARATOR, $open_basedir);
- if ($dirArr && in_array(__DIR__, $dirArr)) {
- $errInfo = '当前服务器因配置了open_basedir,导致无法读取应用根目录';
- }
- }
- if (! $errInfo) {
- $errInfo = '权限不足,无法写入配置文件.env';
- }
- } else {
- $dirArr = [];
- foreach ($checkDirs as $k => $v) {
- if (! is_dir(ROOT_PATH.$v)) {
- $errInfo = '请先在'.$name.'根目录下执行<b>php composer.phar install</b> 安装依赖';
- break;
- }
- }
- }
- // 当前是POST请求
- if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST') {
- if ($errInfo) {
- echo $errInfo;
- exit;
- }
- $err = '';
- $APP_KEY = md5(time().mt_rand(1, 1000000));
- $DB_HOST = isset($_POST['mysqlHost']) ? trim($_POST['mysqlHost']) : '127.0.0.1';
- $DB_PORT = isset($_POST['mysqlPort']) ? trim($_POST['mysqlPort']) : 3306;
- $hostArr = explode(':', $DB_HOST);
- if (count($hostArr) > 1) {
- $DB_HOST = $hostArr[0];
- $DB_PORT = $hostArr[1];
- }
- $DB_USERNAME = isset($_POST['mysqlUsername']) ? trim($_POST['mysqlUsername']) : 'proxypanel';
- $DB_PASSWORD = isset($_POST['mysqlPassword']) ? trim($_POST['mysqlPassword']) : 'proxypanel';
- $DB_DATABASE = isset($_POST['mysqlDatabase']) ? trim($_POST['mysqlDatabase']) : 'proxypanel';
- try {
- // 检测能否读取数据库文件
- $sql = @file_get_contents(DB_PATH);
- if (! $sql) {
- throw new Exception('无法读取所需的'.DB_PATH.',请检查是否有读权限');
- }
- $config = @file_get_contents($exampleConfigFile);
- if (! $config) {
- throw new Exception('无法读取配置.env.example文件,请检查是否有读权限');
- }
- $pdo = new PDO("mysql:host={$DB_HOST};port={$DB_PORT}", $DB_USERNAME, $DB_PASSWORD, [
- PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
- PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
- ]);
- // 检测是否支持innodb存储引擎
- $pdoStatement = $pdo->query("SHOW VARIABLES LIKE 'innodb_version'");
- $result = $pdoStatement->fetch();
- if (! $result) {
- throw new Exception('当前数据库不支持innodb存储引擎,请开启后再重新尝试安装');
- }
- $pdo->query("CREATE DATABASE IF NOT EXISTS `{$DB_DATABASE}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;");
- $pdo->query("USE `{$DB_DATABASE}`");
- $pdo->exec($sql);
- // 写入数据库配置到.env文件
- $callback = function ($matches) use ($APP_KEY, $DB_HOST, $DB_PORT, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE) {
- $field = $matches[1];
- $replace = ${"{$field}"};
- return "{$matches[1]}={$replace}".PHP_EOL;
- };
- $config = preg_replace_callback("/(APP_KEY|DB_HOST|DB_DATABASE|DB_USERNAME|DB_PASSWORD|DB_PORT)=(.*)(\s+)/",
- $callback, $config);
- $result = @file_put_contents($ConfigFile, $config);
- if (! $result) {
- throw new Exception('无法写入数据库信息到.env文件,请检查是否有写权限');
- }
- echo 'success';
- } catch (PDOException $e) {
- $err = $e->getMessage();
- } catch (Exception $e) {
- $err = $e->getMessage();
- }
- echo $err;
- exit;
- }
- ?>
- <!doctype html>
- <html>
- <head>
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <title>安装<?php
- echo $name; ?></title>
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
- <meta name="renderer" content="webkit">
- <style>
- body {
- background: #5c97bd;
- margin: 0;
- padding: 0;
- line-height: 1.5;
- }
- body, input, button {
- font-family: 'Open Sans', sans-serif;
- font-size: 16px;
- color: #fff;
- }
- .container {
- max-width: 515px;
- margin: 0 auto;
- padding: 20px;
- text-align: center;
- }
- a {
- color: #fff7d0;
- text-decoration: none;
- }
- a:hover {
- text-decoration: underline;
- }
- h1 {
- margin-top: 0;
- margin-bottom: 10px;
- }
- h2 {
- font-size: 28px;
- font-weight: normal;
- color: #fff;
- margin-bottom: 0;
- }
- form {
- margin-top: 40px;
- }
- .form-group {
- margin-bottom: 20px;
- }
- .form-group .form-field:first-child input {
- border-top-left-radius: 4px;
- border-top-right-radius: 4px;
- }
- .form-group .form-field:last-child input {
- border-bottom-left-radius: 4px;
- border-bottom-right-radius: 4px;
- }
- .form-field input {
- background: #6ba3c8;
- margin: 0 0 1px;
- border: 2px solid transparent;
- transition: background 0.2s, border-color 0.2s, color 0.2s;
- width: 100%;
- padding: 15px 15px 15px 180px;
- box-sizing: border-box;
- }
- .form-field input:focus {
- border-color: #e8f6ff;
- outline: none;
- }
- .form-field label {
- float: left;
- width: 160px;
- text-align: right;
- margin-right: -160px;
- position: relative;
- margin-top: 18px;
- font-size: 14px;
- pointer-events: none;
- opacity: 0.7;
- }
- button, .btn {
- background: #fff;
- color: #6ba3ca;
- border: 0;
- font-weight: bold;
- border-radius: 4px;
- cursor: pointer;
- padding: 15px 30px;
- -webkit-appearance: none;
- }
- button[disabled] {
- opacity: 0.5;
- }
- #error, .error, #success, .success {
- background: #d66c6c;
- color: #fff;
- padding: 15px 20px;
- border-radius: 4px;
- margin-bottom: 20px;
- }
- #success {
- background: #3C5675;
- }
- #error a, .error a {
- color: white;
- text-decoration: underline;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <h2>安装 <?php
- echo $name; ?></h2>
- <div>
- <form method="post">
- <?php
- if ($errInfo) { ?>
- <div class="error">
- <?php
- echo $errInfo; ?>
- </div>
- <?php
- } ?>
- <div id="error" style="display:none"></div>
- <div id="success" style="display:none"></div>
- <div class="form-group">
- <div class="form-field">
- <label>MySQL 数据库地址</label>
- <input type="text" name="mysqlHost" value="127.0.0.1" required="">
- </div>
- <div class="form-field">
- <label>MySQL 数据库名</label>
- <input type="text" name="mysqlDatabase" value="proxypanel" required="">
- </div>
- <div class="form-field">
- <label>MySQL 用户名</label>
- <input type="text" name="mysqlUsername" value="proxypanel" required="">
- </div>
- <div class="form-field">
- <label>MySQL 密码</label>
- <input type="password" name="mysqlPassword">
- </div>
- <div class="form-field">
- <label>MySQL 端口号</label>
- <input type="number" name="mysqlPort" value="3306">
- </div>
- </div>
- <div class="form-buttons">
- <button type="submit" <?php
- echo $errInfo ? 'disabled' : '' ?>>安装
- </button>
- </div>
- </form>
- <script src="//cdn.staticfile.org/jquery/2.1.4/jquery.min.js" type="text/javascript"></script>
- <script>
- $(function() {
- $('form').on('submit', function(e) {
- e.preventDefault();
- var $button = $(this).find('button').text('安装中...').prop('disabled', true);
- $.post('', $(this).serialize()).done(function(ret) {
- if (ret === 'success') {
- $('#error').hide();
- $('#success').text('安装成功,请使用[用户名:test@test.com、密码:123456]登录').show();
- $('<a class="btn" href="./admin/login">登录后台</a>').insertAfter($button);
- $button.remove();
- localStorage.setItem('fastep', 'installed');
- }
- else {
- $('#error').show().text(ret);
- $button.prop('disabled', false).text('点击安装');
- $('html,body').animate({
- scrollTop: 0,
- }, 500);
- }
- }).fail(function(data) {
- $('#error').show().text('发生错误:\n\n' + data.responseText);
- $button.prop('disabled', false).text('点击安装');
- $('html,body').animate({
- scrollTop: 0,
- }, 500);
- });
- return false;
- });
- });
- </script>
- </div>
- </div>
- </body>
- </html>
|