tougao/install.php
Snowz bbbf936bdd feat: 重构数据库配置并支持多数据库类型
- 将数据库配置从硬编码改为从外部文件加载
- 支持MySQL 5.7+和SQLite两种数据库类型
- 改进安装向导流程,增加数据库类型选择
- 更新README文档说明数据库要求
- 替换CDN链接为国内镜像源
- 增加安装完成后的安全提醒

重构数据库类以支持更灵活的配置方式,包括端口设置和MySQL 5.7兼容性处理。安装向导现在可以正确配置SQLite或MySQL数据库,并生成相应的配置文件。同时优化了前端资源加载速度。
2025-05-26 18:22:24 +08:00

489 lines
16 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* 安装脚本
* 用于初始化数据库和检查环境
*/
if (file_exists(__DIR__ . '/install.lock') && (!isset($_GET['step']) || $_GET['step'] != 4)) {
header('Location: index.php');
exit('系统已安装,请勿重复安装!');
}
$step = $_GET['step'] ?? 1;
$message = '';
$message_type = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($step == 2) {
// 数据库配置并测试连接
$db_type = $_POST['db_type'];
if ($db_type === 'sqlite') {
$sqlite_path = __DIR__ . '/data/submission.db';
if (!is_dir(__DIR__ . '/data')) mkdir(__DIR__ . '/data', 0777, true);
$config = [
'type' => 'sqlite',
'sqlite_path' => $sqlite_path,
'host' => '',
'port' => '',
'db_name' => '',
'username' => '',
'password' => ''
];
} else {
$config = [
'type' => 'mysql',
'host' => $_POST['db_host'],
'port' => $_POST['db_port'],
'db_name' => $_POST['db_name'],
'username' => $_POST['db_user'],
'password' => $_POST['db_pass'],
'sqlite_path' => ''
];
}
require_once __DIR__ . '/config/database.php';
try {
file_put_contents(__DIR__ . '/config/db_config.php', "<?php\nreturn " . var_export($config, true) . ";\n");
$db = (new Database())->getConnection();
$message = '数据库连接成功!';
$message_type = 'success';
header('Location: install.php?step=3');
exit;
} catch (Exception $e) {
if (file_exists(__DIR__ . '/config/db_config.php')) {
unlink(__DIR__ . '/config/db_config.php');
}
$message = $e->getMessage();
$message_type = 'error';
}
} elseif ($step == 3) {
// 初始化数据库表结构可复用你原有的表结构SQL
// ...
file_put_contents(__DIR__ . '/install.lock', 'installed');
header('Location: install.php?step=4');
exit;
}
}
// 环境检查
function checkEnvironment() {
$checks = [
'PHP版本 >= 7.4' => version_compare(PHP_VERSION, '7.4.0', '>='),
'PDO扩展' => extension_loaded('pdo'),
'PDO MySQL扩展' => extension_loaded('pdo_mysql'),
'PDO SQLite扩展' => extension_loaded('pdo_sqlite'),
'GD扩展' => extension_loaded('gd'),
'cURL扩展' => extension_loaded('curl'),
'config目录可写' => is_writable(__DIR__ . '/config'),
'data目录可写' => is_writable(__DIR__ . '/data') || mkdir(__DIR__ . '/data', 0755, true)
];
return $checks;
}
$env_checks = checkEnvironment();
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>安装向导 - 内容投稿系统</title>
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 600px;
margin: 0 auto;
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
overflow: hidden;
backdrop-filter: blur(10px);
}
.header {
background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
color: white;
padding: 40px;
text-align: center;
}
.header h1 {
font-size: 2rem;
font-weight: 700;
margin-bottom: 10px;
}
.step-indicator {
display: flex;
justify-content: center;
gap: 10px;
margin-top: 20px;
}
.step {
width: 30px;
height: 30px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.3);
display: flex;
align-items: center;
justify-content: center;
font-weight: 600;
}
.step.active {
background: white;
color: #4f46e5;
}
.step.completed {
background: #10b981;
color: white;
}
.content {
padding: 40px;
}
.message {
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
font-weight: 500;
}
.message.success {
background: #d1fae5;
color: #065f46;
border: 1px solid #10b981;
}
.message.error {
background: #fee2e2;
color: #991b1b;
border: 1px solid #ef4444;
}
.check-list {
list-style: none;
margin-bottom: 20px;
}
.check-item {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 0;
border-bottom: 1px solid #e5e7eb;
}
.check-item:last-child {
border-bottom: none;
}
.check-icon {
width: 20px;
text-align: center;
}
.check-icon.success {
color: #10b981;
}
.check-icon.error {
color: #ef4444;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: #374151;
}
.form-group input,
.form-group select {
width: 100%;
padding: 12px 16px;
border: 2px solid #e5e7eb;
border-radius: 8px;
font-size: 16px;
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: #4f46e5;
}
.btn {
padding: 12px 24px;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 8px;
}
.btn-primary {
background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
color: white;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(79, 70, 229, 0.3);
}
.btn-success {
background: #10b981;
color: white;
}
.btn-success:hover {
background: #059669;
}
.actions {
display: flex;
gap: 15px;
justify-content: center;
margin-top: 30px;
}
.db-option {
padding: 20px;
border: 2px solid #e5e7eb;
border-radius: 8px;
margin-bottom: 15px;
cursor: pointer;
transition: all 0.3s ease;
}
.db-option:hover {
border-color: #4f46e5;
}
.db-option.selected {
border-color: #4f46e5;
background: #f0f9ff;
}
.db-config {
display: none;
margin-top: 20px;
padding: 20px;
background: #f8fafc;
border-radius: 8px;
}
.db-config.active {
display: block;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1><i class="fas fa-cogs"></i> 安装向导</h1>
<p>内容投稿系统安装配置</p>
<div class="step-indicator">
<div class="step <?php echo $step >= 1 ? ($step > 1 ? 'completed' : 'active') : ''; ?>">1</div>
<div class="step <?php echo $step >= 2 ? ($step > 2 ? 'completed' : 'active') : ''; ?>">2</div>
<div class="step <?php echo $step >= 3 ? ($step > 3 ? 'completed' : 'active') : ''; ?>">3</div>
<div class="step <?php echo $step >= 4 ? 'active' : ''; ?>">4</div>
</div>
</div>
<div class="content">
<?php if ($message): ?>
<div class="message <?php echo $message_type; ?>">
<?php echo htmlspecialchars($message); ?>
</div>
<?php endif; ?>
<?php if ($step == 1): ?>
<!-- 步骤1: 环境检查 -->
<h2>环境检查</h2>
<p>正在检查服务器环境是否满足运行要求...</p>
<ul class="check-list">
<?php foreach ($env_checks as $name => $status): ?>
<li class="check-item">
<div class="check-icon <?php echo $status ? 'success' : 'error'; ?>">
<i class="fas <?php echo $status ? 'fa-check' : 'fa-times'; ?>"></i>
</div>
<span><?php echo $name; ?></span>
</li>
<?php endforeach; ?>
</ul>
<?php if (array_product($env_checks)): ?>
<div class="actions">
<a href="?step=2" class="btn btn-primary">
<i class="fas fa-arrow-right"></i> 下一步
</a>
</div>
<?php else: ?>
<div class="message error">
<i class="fas fa-exclamation-triangle"></i>
环境检查未通过,请先解决上述问题后再继续安装。
</div>
<?php endif; ?>
<?php elseif ($step == 2): ?>
<!-- 步骤2: 数据库配置 -->
<h2>数据库配置</h2>
<p>请选择数据库类型并配置连接信息。</p>
<form method="POST">
<div class="db-option" onclick="selectDatabase('mysql')">
<h3><i class="fas fa-database"></i> MySQL数据库</h3>
<p>适合生产环境,性能更好,支持并发访问</p>
</div>
<div class="db-option" onclick="selectDatabase('sqlite')">
<h3><i class="fas fa-file-alt"></i> SQLite数据库</h3>
<p>适合小型站点,无需额外配置,开箱即用</p>
</div>
<input type="hidden" name="db_type" id="db_type" value="mysql">
<div class="db-config" id="mysql-config">
<h4>MySQL配置</h4>
<div class="form-group">
<label for="db_host">数据库主机</label>
<input type="text" name="db_host" id="db_host" value="localhost" required>
</div>
<div class="form-group">
<label for="db_port">端口</label>
<input type="text" name="db_port" id="db_port" value="3306" required>
</div>
<div class="form-group">
<label for="db_name">数据库名称</label>
<input type="text" name="db_name" id="db_name" value="submission_system" required>
</div>
<div class="form-group">
<label for="db_user">用户名</label>
<input type="text" name="db_user" id="db_user" value="root" required>
</div>
<div class="form-group">
<label for="db_pass">密码</label>
<input type="password" name="db_pass" id="db_pass">
</div>
</div>
<div class="db-config" id="sqlite-config">
<h4>SQLite配置</h4>
<p>SQLite数据库将自动创建在 data/submission.db 文件中,无需额外配置。</p>
</div>
<div class="actions">
<button type="submit" class="btn btn-primary">
<i class="fas fa-check"></i> 测试连接
</button>
</div>
</form>
<?php elseif ($step == 3): ?>
<!-- 步骤3: 初始化数据库 -->
<h2>初始化数据库</h2>
<p>数据库连接成功!现在将创建必要的数据表。</p>
<form method="POST">
<div class="actions">
<button type="submit" class="btn btn-primary">
<i class="fas fa-database"></i> 初始化数据库
</button>
</div>
</form>
<?php elseif ($step == 4): ?>
<!-- 步骤4: 安装完成 -->
<h2>安装完成</h2>
<div class="message success">
<i class="fas fa-check-circle"></i>
恭喜!内容投稿系统安装成功!
</div>
<h3>安全提醒</h3>
<div class="message error">
<i class="fas fa-exclamation-triangle"></i>
为了系统安全,请立即删除或重命名 install.php 文件!
</div>
<h3>默认管理员账户</h3>
<p><strong>用户名:</strong>admin</p>
<p><strong>密码:</strong>admin</p>
<p style="color: #ef4444; margin-top: 10px;">⚠️ 请登录后台后立即修改默认密码!</p>
<h3>下一步操作</h3>
<ul style="margin: 20px 0; padding-left: 20px;">
<li>删除或重命名 install.php 文件以确保安全</li>
<li>配置Web服务器如Apache、Nginx</li>
<li>设置适当的文件权限</li>
<li>登录管理后台修改默认密码</li>
</ul>
<div class="actions">
<a href="index.php" class="btn btn-primary">
<i class="fas fa-home"></i> 访问前台
</a>
<a href="admin/login.php" class="btn btn-success">
<i class="fas fa-shield-alt"></i> 管理后台
</a>
</div>
<?php endif; ?>
</div>
</div>
<script>
function selectDatabase(type) {
// 移除所有选中状态
document.querySelectorAll('.db-option').forEach(option => {
option.classList.remove('selected');
});
// 隐藏所有配置
document.querySelectorAll('.db-config').forEach(config => {
config.classList.remove('active');
});
// 选中当前选项
event.currentTarget.classList.add('selected');
// 显示对应配置
document.getElementById(type + '-config').classList.add('active');
// 设置表单值
document.getElementById('db_type').value = type;
}
// 默认选择MySQL
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('.db-option').click();
});
</script>
</body>
</html>