isInstalled()) { $this->step = 5; // 已安装状态 return; } // 处理消息提示 if (isset($_SESSION['install_message'])) { $this->message = $_SESSION['install_message']; $this->messageType = $_SESSION['install_message_type']; unset($_SESSION['install_message'], $_SESSION['install_message_type']); } // 设置当前步骤 $this->step = $currentStep; } public function index() { // 已安装则显示提示(步骤4除外) if ($this->step == 5) { $this->renderHeader(); $this->alreadyInstalled(); $this->renderFooter(); return; } // 处理表单提交(在输出任何内容之前) $this->handleSubmission(); // 输出页面 $this->renderHeader(); switch ($this->step) { case 1: $this->checkEnvironment(); break; case 2: $this->databaseForm(); break; case 3: $this->adminForm(); break; case 4: $this->finish(); break; default: $this->setMessage('非法步骤', 'error'); $this->showMessage(); } $this->renderFooter(); } // 处理表单提交 protected function handleSubmission() { if ($_SERVER['REQUEST_METHOD'] !== 'POST') { return; } $currentStep = $_POST['step'] ?? 1; switch ($currentStep) { case 2: $this->processDatabaseForm(); break; case 3: $this->processAdminForm(); break; } } // 处理数据库表单提交 protected function processDatabaseForm() { $host = $_POST['db_host'] ?? ''; $name = $_POST['db_name'] ?? ''; $user = $_POST['db_user'] ?? ''; $pass = $_POST['db_pass'] ?? ''; try { // 连接数据库服务器 $pdo = new \PDO("mysql:host=$host;charset=utf8mb4", $user, $pass); $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); // 检查数据库是否存在 $stmt = $pdo->query("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$name'"); $dbExists = $stmt->fetchColumn() !== false; // 如果数据库存在且不为空,提示用户 if ($dbExists) { $stmt = $pdo->query("USE $name"); $stmt = $pdo->query("SHOW TABLES"); if ($stmt->fetchColumn() !== false) { $this->setSessionMessage( "警告:数据库 '$name' 已存在且包含表。继续安装可能会覆盖现有数据。", 'warning' ); return; } } else { // 创建数据库 $pdo->exec("CREATE DATABASE `$name` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); } // 连接到指定数据库 $this->db = new \PDO("mysql:host=$host;dbname=$name;charset=utf8mb4", $user, $pass); $this->db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); // 保存配置文件 $config = " '" . addslashes($host) . "',\n"; $config .= " 'db_name' => '" . addslashes($name) . "',\n"; $config .= " 'db_user' => '" . addslashes($user) . "',\n"; $config .= " 'db_pass' => '" . addslashes($pass) . "',\n];\n"; if (file_put_contents($this->configFile, $config) === false) { throw new \Exception("无法写入配置文件,请检查权限"); } $this->setSessionMessage('数据库配置成功!即将进入管理员设置', 'success'); header("Location: ?step=3"); exit; } catch (\Exception $e) { $this->setSessionMessage('数据库配置失败:' . $e->getMessage(), 'error'); header("Location: ?step=2"); exit; } } // 处理管理员表单提交 protected function processAdminForm() { try { if (!file_exists($this->configFile)) { throw new \Exception("数据库配置文件不存在,请先完成数据库设置"); } $cfg = require $this->configFile; $this->db = new \PDO( "mysql:host={$cfg['db_host']};dbname={$cfg['db_name']};charset=utf8mb4", $cfg['db_user'], $cfg['db_pass'] ); $this->db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); // 创建images表 $this->db->exec(" CREATE TABLE IF NOT EXISTS `images` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `name` varchar(255) NOT NULL COMMENT '文件原名', `newname` varchar(255) NOT NULL COMMENT '新文件名', `url` text NOT NULL COMMENT 'URL', `size` int(11) NOT NULL COMMENT '文件大小(字节)', `width` int(11) NOT NULL COMMENT '宽度(像素)', `height` int(11) NOT NULL COMMENT '高度(像素)', `upload_time` int(11) NOT NULL COMMENT '上传时间戳', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; "); // 创建plugins表 $this->db->exec(" CREATE TABLE IF NOT EXISTS `plugins` ( `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL COMMENT '插件唯一标识,如 SamplePlugin', `title` varchar(255) NOT NULL COMMENT '插件显示名称', `description` text COMMENT '插件描述', `version` varchar(20) DEFAULT NULL COMMENT '插件版本号', `author` varchar(100) DEFAULT NULL COMMENT '作者', `url` varchar(128) NOT NULL, `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '启用状态,1=启用,0=禁用', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='插件管理表'; "); // 创建users表 $this->db->exec(" CREATE TABLE IF NOT EXISTS `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `password` varchar(255) NOT NULL, `email` varchar(100) NOT NULL, `avatar` VARCHAR(128) DEFAULT NULL, `balance` decimal(15,2) NOT NULL DEFAULT '0.00' COMMENT '用户余额', `status` int(11) NOT NULL DEFAULT '0', `role` varchar(20) NOT NULL DEFAULT 'user', `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; "); $username = $_POST['username'] ?? ''; $password = $_POST['password'] ?? ''; $email = $_POST['email'] ?? ''; // 新增邮箱字段 // 验证逻辑更新 if (!$username) { throw new \Exception("用户名不能为空"); } if (!$password) { throw new \Exception("密码不能为空"); } if (strlen($password) < 8) { throw new \Exception("密码长度不能少于8位"); } if (!$email || !filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new \Exception("请输入有效的邮箱地址"); } // 检查用户名是否已存在 $stmt = $this->db->prepare("SELECT id FROM users WHERE username = ?"); $stmt->execute([$username]); if ($stmt->fetchColumn()) { throw new \Exception("用户名 '$username' 已存在,请选择其他用户名"); } // 检查邮箱是否已存在 $stmt = $this->db->prepare("SELECT id FROM users WHERE email = ?"); $stmt->execute([$email]); if ($stmt->fetchColumn()) { throw new \Exception("邮箱 '$email' 已被使用,请选择其他邮箱"); } $hash = password_hash($password, PASSWORD_BCRYPT); // 插入管理员数据(包含邮箱和管理员角色) $stmt = $this->db->prepare(" INSERT INTO users (username, password, email, role, status) VALUES (?, ?, ?, 'admin', 1) "); $stmt->execute([$username, $hash, $email]); // 创建临时标记文件 file_put_contents(ROOT_PATH . "Db/install_completed.tmp", date('Y-m-d H:i:s') . "\n"); $this->setSessionMessage('管理员账号创建成功!安装已完成', 'success'); header("Location: ?step=4"); exit; } catch (\Exception $e) { $this->setSessionMessage('管理员账号创建失败:' . $e->getMessage(), 'error'); header("Location: ?step=3"); exit; } } // 渲染页面头部和样式 protected function renderHeader() { ?> 系统安装向导

系统安装向导

请按照步骤完成系统安装

环境检测
数据库设置
管理员设置
完成
showMessage(); ?>

© 2025 系统安装向导

message)) { return; } $icon = ''; $class = ''; switch ($this->messageType) { case 'success': $icon = 'fa-check-circle'; $class = 'bg-green-50 border-green-200 text-green-700'; break; case 'error': $icon = 'fa-exclamation-circle'; $class = 'bg-red-50 border-red-200 text-red-700'; break; case 'warning': $icon = 'fa-exclamation-triangle'; $class = 'bg-yellow-50 border-yellow-200 text-yellow-700'; break; default: $icon = 'fa-info-circle'; $class = 'bg-blue-50 border-blue-200 text-blue-700'; } echo "
$this->message
"; } // 设置消息 protected function setMessage($message, $type = 'info') { $this->message = $message; $this->messageType = $type; } // 设置会话消息(用于跳转后显示) protected function setSessionMessage($message, $type = 'info') { if (session_status() == PHP_SESSION_NONE) { session_start(); } $_SESSION['install_message'] = $message; $_SESSION['install_message_type'] = $type; } // 检查是否已安装 protected function isInstalled() { return file_exists($this->installedLockFile); } // 已安装提示 protected function alreadyInstalled() { echo "

系统已安装

检测到系统已经安装,如需重新安装,请先删除安装锁定文件:
{$this->installedLockFile}

登录后台
"; } // 第一步:检测环境 protected function checkEnvironment() { $phpVersion = PHP_VERSION; $extensions = [ 'pdo_mysql' => 'MySQL PDO 驱动(必须)', 'mbstring' => '多字节字符串支持(必须)', 'json' => 'JSON 解析支持(必须)', 'openssl' => 'OpenSSL 加密扩展(必须)', 'fileinfo' => '文件信息扩展(必须)', 'pdo' => 'PDO 基础扩展(可选,一般随 pdo_mysql 自动启用)' ]; $writableDirs = [ ROOT_PATH . "Db" => "数据库配置目录", ROOT_PATH . "Storage" => "文件存储目录" ]; // 检查PHP版本 $phpVersionOk = version_compare($phpVersion, '8.0.0', '>='); // 检查扩展 $allExtensionsOk = true; $extensionResults = []; foreach ($extensions as $ext => $desc) { $installed = extension_loaded($ext); if (!$installed && $ext !== 'pdo') { // pdo 可选 $allExtensionsOk = false; } $extensionResults[] = [ 'name' => $ext, 'desc' => $desc, 'installed' => $installed ]; } // 检查目录写权限(真实写入测试) $allDirsWritable = true; $dirResults = []; foreach ($writableDirs as $dir => $desc) { if (!is_dir($dir)) { mkdir($dir, 0755, true); } $testFile = $dir . '/.test'; $canWrite = @file_put_contents($testFile, 'test') !== false; if ($canWrite) { unlink($testFile); } else { $allDirsWritable = false; } $dirResults[] = [ 'path' => $dir, 'desc' => $desc, 'writable' => $canWrite ]; } // 检查 PHP 配置 $fileUploadsOk = ini_get('file_uploads'); echo "

环境检测

"; // PHP版本检查 echo "

PHP版本

需要PHP 8.0.0或更高版本

" . ($phpVersionOk ? '✅' : '❌') . "

当前版本: $phpVersion

"; // 扩展检查 echo "

必要扩展

"; foreach ($extensionResults as $ext) { echo "
{$ext['desc']} ({$ext['name']}) " . ($ext['installed'] ? '✅' : '❌') . "
"; if (!$ext['installed']) { echo "

Linux 安装命令示例: apt install php-{$ext['name']}

"; } echo "
"; } echo "
"; // 文件权限检查 echo "

文件权限

"; foreach ($dirResults as $dir) { echo "
{$dir['desc']} ({$dir['path']}) " . ($dir['writable'] ? '✅' : '❌') . "
"; } echo "
"; // PHP 配置检查 echo "
文件上传 (file_uploads) " . ($fileUploadsOk ? '✅' : '❌') . "
"; // 下一步按钮 $allChecksPassed = $phpVersionOk && $allExtensionsOk && $allDirsWritable && $fileUploadsOk; echo "
"; if ($allChecksPassed) { echo " 下一步:数据库设置 "; } else { echo ""; } echo "
"; } // 第二步:数据库表单 protected function databaseForm() { echo "

数据库设置

"; echo '

通常为 localhost 或 127.0.0.1

如果数据库无密码,请留空

上一步
'; } // 第三步:创建管理员 protected function adminForm() { // 检查配置文件是否存在 if (!file_exists($this->configFile)) { $this->setMessage('数据库配置文件不存在,请先完成数据库设置', 'error'); $this->showMessage(); echo "
返回数据库设置
"; return; } echo '

创建管理员账号

'; echo '

请设置强密码(至少8位,包含字母和数字)

上一步
'; } // 第四步:完成安装 protected function finish() { // 关键修复:在完成页面创建最终的安装锁定文件 if (file_exists(ROOT_PATH . "Db/install_completed.tmp")) { rename(ROOT_PATH . "Db/install_completed.tmp", $this->installedLockFile); } echo "

安装完成!

管理员账号已创建,系统安装成功,您可以登录后台开始使用了。

登录后台 访问首页
"; } }