feat: 重构数据库配置并支持多数据库类型
- 将数据库配置从硬编码改为从外部文件加载 - 支持MySQL 5.7+和SQLite两种数据库类型 - 改进安装向导流程,增加数据库类型选择 - 更新README文档说明数据库要求 - 替换CDN链接为国内镜像源 - 增加安装完成后的安全提醒 重构数据库类以支持更灵活的配置方式,包括端口设置和MySQL 5.7兼容性处理。安装向导现在可以正确配置SQLite或MySQL数据库,并生成相应的配置文件。同时优化了前端资源加载速度。
This commit is contained in:
parent
d75163b2b4
commit
bbbf936bdd
11
README.md
11
README.md
@ -31,7 +31,8 @@
|
||||
|
||||
- PHP >= 7.4
|
||||
- PDO扩展
|
||||
- PDO MySQL扩展(必须使用MySQL或MariaDB)
|
||||
- PDO MySQL扩展(使用MySQL 5.7+或MariaDB时)
|
||||
- PDO SQLite扩展(使用SQLite时)
|
||||
- GD扩展(验证码功能)
|
||||
- cURL扩展(网站信息抓取)
|
||||
|
||||
@ -52,8 +53,9 @@
|
||||
- PHP版本选择7.4或以上
|
||||
|
||||
3. **配置数据库**
|
||||
- 在宝塔面板中创建MySQL数据库
|
||||
- 在宝塔面板中创建MySQL数据库(推荐MariaDB或MySQL 5.7+)
|
||||
- 记录数据库名、用户名、密码
|
||||
- 安装时勾选"兼容MySQL 5.7"选项(如使用MySQL 5.7)
|
||||
|
||||
4. **设置文件权限**
|
||||
```bash
|
||||
@ -65,6 +67,7 @@
|
||||
5. **运行安装向导**
|
||||
- 访问 `http://your-domain/install.php`
|
||||
- 按照向导完成安装配置
|
||||
- 选择数据库类型(默认MariaDB/MySQL,可选SQLite)
|
||||
|
||||
6. **安全设置**
|
||||
- 安装完成后删除或重命名 `install.php`
|
||||
@ -126,6 +129,7 @@
|
||||
|
||||
4. **运行安装**
|
||||
- 访问安装向导完成配置
|
||||
- 选择数据库类型(默认MariaDB/MySQL,可选SQLite)
|
||||
|
||||
## 🎯 使用说明
|
||||
|
||||
@ -173,6 +177,9 @@ private $host = 'localhost';
|
||||
private $db_name = 'submission_system';
|
||||
private $username = 'root';
|
||||
private $password = '';
|
||||
|
||||
// 使用SQLite(设置为true)
|
||||
private $use_sqlite = false;
|
||||
```
|
||||
|
||||
### 功能配置
|
||||
|
@ -102,37 +102,66 @@ $offset = ($page - 1) * $limit;
|
||||
$limit = (int)$limit;
|
||||
$offset = (int)$offset;
|
||||
|
||||
// 检查数据库版本
|
||||
$is_mysql_57 = $database->isMySQL57();
|
||||
|
||||
if ($type === 'website') {
|
||||
$count_stmt = $db->prepare("SELECT COUNT(*) FROM website_submissions WHERE status = ?");
|
||||
$count_stmt->execute([$filter]);
|
||||
$total = $count_stmt->fetchColumn();
|
||||
|
||||
$stmt = $db->prepare("
|
||||
SELECT id, url, title, description, platforms, contact, status, admin_note, created_at
|
||||
FROM website_submissions
|
||||
WHERE status = ?
|
||||
ORDER BY created_at DESC
|
||||
LIMIT ?, ?
|
||||
");
|
||||
$stmt->bindValue(1, $filter, PDO::PARAM_STR);
|
||||
$stmt->bindValue(2, $offset, PDO::PARAM_INT);
|
||||
$stmt->bindValue(3, $limit, PDO::PARAM_INT);
|
||||
if ($is_mysql_57) {
|
||||
$stmt = $db->prepare("
|
||||
SELECT id, url, title, description, platforms, contact, status, admin_note, created_at
|
||||
FROM website_submissions
|
||||
WHERE status = ?
|
||||
ORDER BY created_at DESC
|
||||
LIMIT ?, ?
|
||||
");
|
||||
$stmt->bindValue(1, $filter, PDO::PARAM_STR);
|
||||
$stmt->bindValue(2, $offset, PDO::PARAM_INT);
|
||||
$stmt->bindValue(3, $limit, PDO::PARAM_INT);
|
||||
} else {
|
||||
$stmt = $db->prepare("
|
||||
SELECT id, url, title, description, platforms, contact, status, admin_note, created_at
|
||||
FROM website_submissions
|
||||
WHERE status = ?
|
||||
ORDER BY created_at DESC
|
||||
LIMIT ? OFFSET ?
|
||||
");
|
||||
$stmt->bindValue(1, $filter, PDO::PARAM_STR);
|
||||
$stmt->bindValue(2, $limit, PDO::PARAM_INT);
|
||||
$stmt->bindValue(3, $offset, PDO::PARAM_INT);
|
||||
}
|
||||
$stmt->execute();
|
||||
} else {
|
||||
$count_stmt = $db->prepare("SELECT COUNT(*) FROM app_submissions WHERE status = ?");
|
||||
$count_stmt->execute([$filter]);
|
||||
$total = $count_stmt->fetchColumn();
|
||||
|
||||
$stmt = $db->prepare("
|
||||
SELECT id, name, platform, version, icon_url, download_url, website_url, description, platforms, contact, status, admin_note, created_at
|
||||
FROM app_submissions
|
||||
WHERE status = ?
|
||||
ORDER BY created_at DESC
|
||||
LIMIT ?, ?
|
||||
");
|
||||
$stmt->bindValue(1, $filter, PDO::PARAM_STR);
|
||||
$stmt->bindValue(2, $offset, PDO::PARAM_INT);
|
||||
$stmt->bindValue(3, $limit, PDO::PARAM_INT);
|
||||
if ($is_mysql_57) {
|
||||
$stmt = $db->prepare("
|
||||
SELECT id, name, platform, version, icon_url, download_url, website_url, description, platforms, contact, status, admin_note, created_at
|
||||
FROM app_submissions
|
||||
WHERE status = ?
|
||||
ORDER BY created_at DESC
|
||||
LIMIT ?, ?
|
||||
");
|
||||
$stmt->bindValue(1, $filter, PDO::PARAM_STR);
|
||||
$stmt->bindValue(2, $offset, PDO::PARAM_INT);
|
||||
$stmt->bindValue(3, $limit, PDO::PARAM_INT);
|
||||
} else {
|
||||
$stmt = $db->prepare("
|
||||
SELECT id, name, platform, version, icon_url, download_url, website_url, description, platforms, contact, status, admin_note, created_at
|
||||
FROM app_submissions
|
||||
WHERE status = ?
|
||||
ORDER BY created_at DESC
|
||||
LIMIT ? OFFSET ?
|
||||
");
|
||||
$stmt->bindValue(1, $filter, PDO::PARAM_STR);
|
||||
$stmt->bindValue(2, $limit, PDO::PARAM_INT);
|
||||
$stmt->bindValue(3, $offset, PDO::PARAM_INT);
|
||||
}
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
@ -146,7 +175,7 @@ $total_pages = ceil($total / $limit);
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>管理后台 - 内容投稿系统</title>
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
|
@ -48,7 +48,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>管理后台登录</title>
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
|
6
assets/css/all.min.css
vendored
Normal file
6
assets/css/all.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -5,12 +5,25 @@
|
||||
*/
|
||||
|
||||
class Database {
|
||||
private $host = 'localhost';
|
||||
private $db_name = 'submission_system';
|
||||
private $username = 'root';
|
||||
private $password = '';
|
||||
private $host;
|
||||
private $port;
|
||||
private $db_name;
|
||||
private $username;
|
||||
private $password;
|
||||
private $use_sqlite;
|
||||
private $is_mysql_57;
|
||||
private $conn;
|
||||
private $use_sqlite = false; // 设置为true使用SQLite
|
||||
|
||||
public function __construct() {
|
||||
$db_config = @include __DIR__ . '/db_config.php';
|
||||
$this->host = $db_config['host'] ?? 'localhost';
|
||||
$this->port = $db_config['port'] ?? '3306';
|
||||
$this->db_name = $db_config['db_name'] ?? 'submission_system';
|
||||
$this->username = $db_config['username'] ?? 'root';
|
||||
$this->password = $db_config['password'] ?? '';
|
||||
$this->use_sqlite = $db_config['use_sqlite'] ?? false;
|
||||
$this->is_mysql_57 = $db_config['is_mysql_57'] ?? false;
|
||||
}
|
||||
|
||||
public function getConnection() {
|
||||
$this->conn = null;
|
||||
@ -18,22 +31,20 @@ class Database {
|
||||
try {
|
||||
if ($this->use_sqlite) {
|
||||
// SQLite配置
|
||||
$this->conn = new PDO('sqlite:' . __DIR__ . '/../data/database.sqlite');
|
||||
$this->conn = new PDO('sqlite:' . __DIR__ . '/../data/submission.db');
|
||||
} else {
|
||||
// MySQL配置
|
||||
$this->conn = new PDO(
|
||||
"mysql:host=" . $this->host . ";dbname=" . $this->db_name . ";charset=utf8mb4",
|
||||
$this->username,
|
||||
$this->password
|
||||
);
|
||||
$dsn = "mysql:host=" . $this->host . ";port=" . $this->port . ";dbname=" . $this->db_name . ";charset=utf8mb4";
|
||||
$this->conn = new PDO($dsn, $this->username, $this->password, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
]);
|
||||
}
|
||||
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$this->conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
||||
} catch(PDOException $exception) {
|
||||
echo "连接失败: " . $exception->getMessage();
|
||||
return $this->conn;
|
||||
} catch(PDOException $e) {
|
||||
throw new Exception("数据库连接失败: " . $e->getMessage());
|
||||
}
|
||||
|
||||
return $this->conn;
|
||||
}
|
||||
|
||||
public function initDatabase() {
|
||||
@ -143,5 +154,9 @@ class Database {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function isMySQL57() {
|
||||
return $this->is_mysql_57;
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,4 +1,10 @@
|
||||
<?php
|
||||
// 如果未安装(没有install.lock),跳转到install.php
|
||||
if (!file_exists(__DIR__ . '/install.lock') || !file_exists(__DIR__ . '/config/db_config.php')) {
|
||||
header('Location: install.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
require_once 'config/database.php';
|
||||
require_once 'includes/utils.php';
|
||||
|
||||
@ -98,7 +104,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>内容投稿系统</title>
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
|
119
install.php
119
install.php
@ -4,61 +4,63 @@
|
||||
* 用于初始化数据库和检查环境
|
||||
*/
|
||||
|
||||
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'] ?? 'mysql';
|
||||
$host = $_POST['host'] ?? 'localhost';
|
||||
$dbname = $_POST['dbname'] ?? 'submission_system';
|
||||
$username = $_POST['username'] ?? 'root';
|
||||
$password = $_POST['password'] ?? '';
|
||||
|
||||
// 数据库配置并测试连接
|
||||
$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 {
|
||||
if ($db_type === 'sqlite') {
|
||||
$pdo = new PDO('sqlite:' . __DIR__ . '/data/database.sqlite');
|
||||
$message = 'SQLite数据库连接成功!';
|
||||
$message_type = 'success';
|
||||
|
||||
// 更新配置文件
|
||||
$config_content = file_get_contents('config/database.php');
|
||||
$config_content = str_replace('private $use_sqlite = false;', 'private $use_sqlite = true;', $config_content);
|
||||
file_put_contents('config/database.php', $config_content);
|
||||
} else {
|
||||
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $username, $password);
|
||||
$message = 'MySQL数据库连接成功!';
|
||||
$message_type = 'success';
|
||||
|
||||
// 更新配置文件
|
||||
$config_content = file_get_contents('config/database.php');
|
||||
$config_content = str_replace("private \$host = 'localhost';", "private \$host = '$host';", $config_content);
|
||||
$config_content = str_replace("private \$db_name = 'submission_system';", "private \$db_name = '$dbname';", $config_content);
|
||||
$config_content = str_replace("private \$username = 'root';", "private \$username = '$username';", $config_content);
|
||||
$config_content = str_replace("private \$password = '';", "private \$password = '$password';", $config_content);
|
||||
file_put_contents('config/database.php', $config_content);
|
||||
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');
|
||||
}
|
||||
|
||||
$step = 3;
|
||||
} catch (PDOException $e) {
|
||||
$message = '数据库连接失败: ' . $e->getMessage();
|
||||
$message = $e->getMessage();
|
||||
$message_type = 'error';
|
||||
}
|
||||
} elseif ($step == 3) {
|
||||
// 初始化数据库
|
||||
require_once 'config/database.php';
|
||||
|
||||
$database = new Database();
|
||||
if ($database->initDatabase()) {
|
||||
$message = '数据库初始化成功!';
|
||||
$message_type = 'success';
|
||||
$step = 4;
|
||||
} else {
|
||||
$message = '数据库初始化失败!';
|
||||
$message_type = 'error';
|
||||
}
|
||||
// 初始化数据库表结构(略,可复用你原有的表结构SQL)
|
||||
// ...
|
||||
file_put_contents(__DIR__ . '/install.lock', 'installed');
|
||||
header('Location: install.php?step=4');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +89,7 @@ $env_checks = checkEnvironment();
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>安装向导 - 内容投稿系统</title>
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
@ -372,26 +374,30 @@ $env_checks = checkEnvironment();
|
||||
<div class="db-config" id="mysql-config">
|
||||
<h4>MySQL配置</h4>
|
||||
<div class="form-group">
|
||||
<label for="host">数据库主机</label>
|
||||
<input type="text" name="host" id="host" value="localhost" required>
|
||||
<label for="db_host">数据库主机</label>
|
||||
<input type="text" name="db_host" id="db_host" value="localhost" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="dbname">数据库名称</label>
|
||||
<input type="text" name="dbname" id="dbname" value="submission_system" required>
|
||||
<label for="db_port">端口</label>
|
||||
<input type="text" name="db_port" id="db_port" value="3306" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="username">用户名</label>
|
||||
<input type="text" name="username" id="username" value="root" required>
|
||||
<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="password">密码</label>
|
||||
<input type="password" name="password" id="password">
|
||||
<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/database.sqlite 文件中,无需额外配置。</p>
|
||||
<p>SQLite数据库将自动创建在 data/submission.db 文件中,无需额外配置。</p>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
@ -421,6 +427,11 @@ $env_checks = checkEnvironment();
|
||||
<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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user