本文目录导读:

我来为您创建一个完整的PHP动态配置管理后台,包含数据库设计、后端API和前端界面。
数据库设计
-- 创建配置表
CREATE TABLE `configurations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`config_key` varchar(100) NOT NULL COMMENT '配置键名',
`config_value` text COMMENT '配置值',
`config_type` enum('text','textarea','number','select','checkbox','json') DEFAULT 'text' COMMENT '配置类型',
`config_group` varchar(50) DEFAULT 'general' COMMENT '配置分组',
`description` varchar(255) DEFAULT NULL COMMENT '配置说明',
`options` text COMMENT '选项值(JSON格式)',
`is_required` tinyint(1) DEFAULT '0' COMMENT '是否必填',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_config_key` (`config_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 示例数据
INSERT INTO `configurations` (`config_key`, `config_value`, `config_type`, `config_group`, `description`, `options`, `is_required`) VALUES
('site_name', 'My Website', 'text', 'general', '网站名称', NULL, 1),
('site_url', 'https://example.com', 'text', 'general', '网站URL', NULL, 1),
('site_description', '这是网站描述', 'textarea', 'general', '网站描述', NULL, 0),
('items_per_page', '20', 'number', 'pagination', '每页显示数量', NULL, 1),
('theme_color', 'blue', 'select', 'appearance', '主题颜色', '["blue","red","green","dark"]', 0),
('enable_registration', '1', 'checkbox', 'user', '开放注册', NULL, 0),
('api_settings', '{"timeout":30,"retry":3}', 'json', 'api', 'API设置', NULL, 0);
后端PHP代码
config.php - 数据库连接
<?php
// config.php
session_start();
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_NAME', 'config_demo');
// 创建数据库连接
$conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$conn->set_charset("utf8mb4");
// 辅助函数
function json_response($data, $status = 200) {
http_response_code($status);
header('Content-Type: application/json');
echo json_encode($data);
exit;
}
function validate_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
get_configs.php - 获取配置列表
<?php
require_once 'config.php';
header('Content-Type: application/json');
$sql = "SELECT * FROM configurations ORDER BY config_group, config_key";
$result = $conn->query($sql);
$configs = [];
while ($row = $result->fetch_assoc()) {
// 解析JSON选项
if ($row['options']) {
$row['options'] = json_decode($row['options'], true);
}
// 解析JSON值
if ($row['config_type'] === 'json' && $row['config_value']) {
$row['config_value'] = json_decode($row['config_value'], true);
}
$configs[] = $row;
}
json_response(['success' => true, 'data' => $configs]);
?>
save_config.php - 保存配置
<?php
require_once 'config.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
json_response(['success' => false, 'message' => 'Invalid request method'], 400);
}
// 获取请求数据
$input = json_decode(file_get_contents('php://input'), true);
if (!$input || !isset($input['id']) || !isset($input['value'])) {
json_response(['success' => false, 'message' => 'Invalid data'], 400);
}
$id = intval($input['id']);
$value = $input['value'];
// 获取配置信息
$stmt = $conn->prepare("SELECT * FROM configurations WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result();
$config = $result->fetch_assoc();
if (!$config) {
json_response(['success' => false, 'message' => 'Configuration not found'], 404);
}
// 根据类型处理值
$valueToSave = $value;
switch ($config['config_type']) {
case 'checkbox':
$valueToSave = $value ? '1' : '0';
break;
case 'json':
if (is_array($value)) {
$valueToSave = json_encode($value);
} else {
// 尝试解析JSON字符串
$decoded = json_decode($value, true);
if (json_last_error() === JSON_ERROR_NONE) {
$valueToSave = json_encode($decoded);
} else {
json_response(['success' => false, 'message' => 'Invalid JSON format'], 400);
}
}
break;
case 'number':
if (!is_numeric($value)) {
json_response(['success' => false, 'message' => 'Invalid number'], 400);
}
break;
default:
$valueToSave = validate_input((string)$value);
}
// 更新配置
$stmt = $conn->prepare("UPDATE configurations SET config_value = ?, updated_at = NOW() WHERE id = ?");
$stmt->bind_param("si", $valueToSave, $id);
if ($stmt->execute()) {
json_response(['success' => true, 'message' => 'Configuration saved successfully']);
} else {
json_response(['success' => false, 'message' => 'Failed to save configuration'], 500);
}
?>
delete_config.php - 删除配置
<?php
require_once 'config.php';
if ($_SERVER['REQUEST_METHOD'] !== 'DELETE') {
json_response(['success' => false, 'message' => 'Invalid request method'], 400);
}
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
if (!$id) {
json_response(['success' => false, 'message' => 'Invalid ID'], 400);
}
$stmt = $conn->prepare("DELETE FROM configurations WHERE id = ?");
$stmt->bind_param("i", $id);
if ($stmt->execute()) {
json_response(['success' => true, 'message' => 'Configuration deleted successfully']);
} else {
json_response(['success' => false, 'message' => 'Failed to delete configuration'], 500);
}
?>
add_config.php - 添加配置
<?php
require_once 'config.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
json_response(['success' => false, 'message' => 'Invalid request method'], 400);
}
$input = json_decode(file_get_contents('php://input'), true);
// 验证必填字段
if (!isset($input['config_key']) || !isset($input['config_key'])) {
json_response(['success' => false, 'message' => 'Config key is required'], 400);
}
$config_key = validate_input($input['config_key']);
$config_value = isset($input['config_value']) ? validate_input($input['config_value']) : '';
$config_type = isset($input['config_type']) ? validate_input($input['config_type']) : 'text';
$config_group = isset($input['config_group']) ? validate_input($input['config_group']) : 'general';
$description = isset($input['description']) ? validate_input($input['description']) : '';
$is_required = isset($input['is_required']) ? intval($input['is_required']) : 0;
$options = isset($input['options']) ? json_encode($input['options']) : NULL;
// 检查key是否已存在
$stmt = $conn->prepare("SELECT id FROM configurations WHERE config_key = ?");
$stmt->bind_param("s", $config_key);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
json_response(['success' => false, 'message' => 'Config key already exists'], 400);
}
$stmt = $conn->prepare("INSERT INTO configurations (config_key, config_value, config_type, config_group, description, options, is_required) VALUES (?, ?, ?, ?, ?, ?, ?)");
$stmt->bind_param("ssssssi", $config_key, $config_value, $config_type, $config_group, $description, $options, $is_required);
if ($stmt->execute()) {
json_response(['success' => true, 'message' => 'Configuration added successfully', 'id' => $conn->insert_id]);
} else {
json_response(['success' => false, 'message' => 'Failed to add configuration'], 500);
}
?>
get_config_value.php - 获取单个配置值
<?php
require_once 'config.php';
// 获取特定配置值(用于前端)
$key = isset($_GET['key']) ? validate_input($_GET['key']) : '';
if (!$key) {
json_response(['success' => false, 'message' => 'Config key is required'], 400);
}
$stmt = $conn->prepare("SELECT config_value, config_type FROM configurations WHERE config_key = ? LIMIT 1");
$stmt->bind_param("s", $key);
$stmt->execute();
$result = $stmt->get_result();
if ($row = $result->fetch_assoc()) {
// 根据类型转换值
$value = $row['config_value'];
switch ($row['config_type']) {
case 'number':
$value = (float)$value;
break;
case 'checkbox':
$value = (bool)$value;
break;
case 'json':
$value = json_decode($value, true);
break;
}
json_response(['success' => true, 'data' => $value]);
} else {
json_response(['success' => false, 'message' => 'Configuration not found'], 404);
}
?>
前端界面
index.php - 管理后台主页面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">配置管理后台</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
.config-section {
margin-bottom: 30px;
}
.config-section h3 {
border-bottom: 2px solid #007bff;
padding-bottom: 10px;
margin-bottom: 20px;
}
.config-item {
margin-bottom: 15px;
}
.config-card {
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
border: 1px solid #dee2e6;
border-radius: 8px;
}
.config-card .card-body {
padding: 15px;
}
.edit-btn, .delete-btn {
cursor: pointer;
}
.toast-container {
position: fixed;
top: 20px;
right: 20px;
z-index: 1050;
}
.loading {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#sidebar {
min-height: 100vh;
background: #343a40;
color: white;
padding: 20px;
}
#sidebar a {
color: white;
text-decoration: none;
display: block;
padding: 10px;
margin-bottom: 5px;
border-radius: 5px;
}
#sidebar a:hover {
background: #007bff;
}
#sidebar a.active {
background: #007bff;
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="row">
<!-- 侧边栏 -->
<nav id="sidebar" class="col-md-2 d-md-block">
<h4 class="text-center mb-4">配置管理</h4>
<a href="#general" class="active" data-group="general"><i class="fas fa-cog"></i> 通用设置</a>
<a href="#appearance" data-group="appearance"><i class="fas fa-palette"></i> 外观设置</a>
<a href="#user" data-group="user"><i class="fas fa-user"></i> 用户设置</a>
<a href="#api" data-group="api"><i class="fas fa-code"></i> API设置</a>
<a href="#system" data-group="system"><i class="fas fa-server"></i> 系统设置</a>
<hr>
<a href="#add-config" data-bs-toggle="modal" data-bs-target="#addConfigModal">
<i class="fas fa-plus"></i> 添加配置
</a>
</nav>
<!-- 主内容 -->
<main class="col-md-10 ms-sm-auto px-md-4">
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">配置管理</h1>
<div class="btn-toolbar mb-2 mb-md-0">
<button class="btn btn-primary" onclick="refreshConfigs()">
<i class="fas fa-refresh"></i> 刷新
</button>
</div>
</div>
<div id="loading" class="loading">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div id="config-content"></div>
</main>
</div>
</div>
<!-- Toast通知 -->
<div class="toast-container" id="toastContainer"></div>
<!-- 添加配置 Modal -->
<div class="modal fade" id="addConfigModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">添加新配置</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="addConfigForm">
<div class="mb-3">
<label class="form-label">配置键名 *</label>
<input type="text" class="form-control" id="configKey" required>
</div>
<div class="mb-3">
<label class="form-label">配置值</label>
<textarea class="form-control" id="configValue"></textarea>
</div>
<div class="mb-3">
<label class="form-label">配置类型</label>
<select class="form-control" id="configType">
<option value="text">文本</option>
<option value="textarea">多行文本</option>
<option value="number">数字</option>
<option value="select">下拉选择</option>
<option value="checkbox">复选框</option>
<option value="json">JSON</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">配置分组</label>
<select class="form-control" id="configGroup">
<option value="general">通用设置</option>
<option value="appearance">外观设置</option>
<option value="user">用户设置</option>
<option value="api">API设置</option>
<option value="system">系统设置</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">描述</label>
<textarea class="form-control" id="configDescription"></textarea>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="configRequired">
<label class="form-check-label">必填</label>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="addConfig()">添加</button>
</div>
</div>
</div>
</div>
<!-- 编辑配置 Modal -->
<div class="modal fade" id="editModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">编辑配置</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="editForm">
<input type="hidden" id="editId">
<div class="mb-3">
<label class="form-label">配置值</label>
<div id="editValueContainer"></div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" onclick="saveEdit()">保存</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
let currentGroup = 'general';
let allConfigs = [];
// 初始化
$(document).ready(function() {
refreshConfigs();
// 侧边栏点击事件
$('.sidebar-item').click(function(e) {
e.preventDefault();
const group = $(this).data('group');
currentGroup = group;
filterByGroup(group);
// 设置激活状态
$('.sidebar-item').removeClass('active');
$(this).addClass('active');
});
});
// 刷新配置
function refreshConfigs() {
$('#loading').show();
$('#config-content').empty();
$.ajax({
url: 'get_configs.php',
method: 'GET',
success: function(response) {
allConfigs = response.data;
filterByGroup(currentGroup);
$('#loading').hide();
},
error: function(xhr) {
showToast('加载配置失败', 'error');
$('#loading').hide();
}
});
}
// 按分组筛选
function filterByGroup(group) {
const filtered = allConfigs.filter(config => config.config_group === group);
renderConfigs(filtered);
}
// 渲染配置
function renderConfigs(configs) {
const content = $('#config-content');
content.empty();
if (configs.length === 0) {
content.html(`
<div class="alert alert-info">
<i class="fas fa-info-circle"></i> 该分组暂无配置项
</div>
`);
return;
}
const html = configs.map(config => {
let valueDisplay = formatValue(config);
return `
<div class="card config-card mb-3">
<div class="card-body">
<div class="row align-items-center">
<div class="col-md-4">
<h6 class="mb-1">${config.config_key}</h6>
<small class="text-muted">${config.description || ''}</small>
</div>
<div class="col-md-6">
${valueDisplay}
</div>
<div class="col-md-2 text-end">
<button class="btn btn-sm btn-outline-primary edit-btn" onclick="openEditModal(${config.id})">
<i class="fas fa-edit"></i>
</button>
<button class="btn btn-sm btn-outline-danger delete-btn" onclick="deleteConfig(${config.id})">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</div>
</div>
`;
}).join('');
content.html(html);
}
// 格式化值显示
function formatValue(config) {
const value = config.config_value;
switch(config.config_type) {
case 'checkbox':
return `
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox"
${value == '1' ? 'checked' : ''} disabled>
<label class="form-check-label">${value == '1' ? '启用' : '禁用'}</label>
</div>
`;
case 'select':
return `<span class="badge bg-primary">${value}</span>`;
case 'json':
try {
const obj = typeof value === 'string' ? JSON.parse(value) : value;
return `<code>${JSON.stringify(obj, null, 2)}</code>`;
} catch(e) {
return `<code>${value}</code>`;
}
case 'textarea':
return `<span class="text-muted">${value?.substring(0, 100)}...</span>`;
default:
return `<span>${value}</span>`;
}
}
// 打开编辑模态框
function openEditModal(id) {
const config = allConfigs.find(c => c.id === id);
if (!config) return;
$('#editId').val(config.id);
$('#editValueContainer').empty();
let inputHtml = '';
switch(config.config_type) {
case 'text':
inputHtml = `<input type="text" class="form-control" id="editValue" value="${config.config_value}">`;
break;
case 'textarea':
inputHtml = `<textarea class="form-control" id="editValue" rows="3">${config.config_value}</textarea>`;
break;
case 'number':
inputHtml = `<input type="number" class="form-control" id="editValue" value="${config.config_value}">`;
break;
case 'select':
const options = config.options || [];
let selectHtml = '<select class="form-control" id="editValue">';
options.forEach(option => {
selectHtml += `<option value="${option}" ${option === config.config_value ? 'selected' : ''}>${option}</option>`;
});
selectHtml += '</select>';
inputHtml = selectHtml;
break;
case 'checkbox':
inputHtml = `
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="editValue" ${config.config_value == '1' ? 'checked' : ''}>
<label class="form-check-label">启用</label>
</div>
`;
break;
case 'json':
const jsonValue = typeof config.config_value === 'string' ? config.config_value : JSON.stringify(config.config_value, null, 2);
inputHtml = `<textarea class="form-control" id="editValue" rows="5">${jsonValue}</textarea>`;
break;
default:
inputHtml = `<input type="text" class="form-control" id="editValue" value="${config.config_value}">`;
}
$('#editValueContainer').html(inputHtml);
const modal = new bootstrap.Modal(document.getElementById('editModal'));
modal.show();
}
// 保存编辑
function saveEdit() {
const id = $('#editId').val();
let value = $('#editValue').val();
// 处理checkbox
if (value === undefined) {
value = $('#editValue').is(':checked') ? '1' : '0';
}
$.ajax({
url: 'save_config.php',
method: 'POST',
data: JSON.stringify({
id: id,
value: value
}),
contentType: 'application/json',
success: function(response) {
if (response.success) {
showToast('配置保存成功', 'success');
refreshConfigs();
const modal = bootstrap.Modal.getInstance(document.getElementById('editModal'));
modal.hide();
} else {
showToast(response.message || '保存失败', 'error');
}
},
error: function(xhr) {
showToast('保存失败', 'error');
}
});
}
// 删除配置
function deleteConfig(id) {
if (!confirm('确定要删除这个配置吗?')) return;
$.ajax({
url: `delete_config.php?id=${id}`,
method: 'DELETE',
success: function(response) {
if (response.success) {
showToast('配置删除成功', 'success');
refreshConfigs();
} else {
showToast(response.message || '删除失败', 'error');
}
},
error: function(xhr) {
showToast('删除失败', 'error');
}
});
}
// 添加配置
function addConfig() {
const data = {
config_key: $('#configKey').val(),
config_value: $('#configValue').val() || '',
config_type: $('#configType').val(),
config_group: $('#configGroup').val(),
description: $('#configDescription').val() || '',
is_required: $('#configRequired').is(':checked') ? 1 : 0
};
$.ajax({
url: 'add_config.php',
method: 'POST',
data: JSON.stringify(data),
contentType: 'application/json',
success: function(response) {
if (response.success) {
showToast('配置添加成功', 'success');
refreshConfigs();
// 关闭模态框并重置表单
const modal = bootstrap.Modal.getInstance(document.getElementById('addConfigModal'));
modal.hide();
$('#addConfigForm')[0].reset();
} else {
showToast(response.message || '添加失败', 'error');
}
},
error: function(xhr) {
showToast('添加失败', 'error');
}
});
}
// 显示Toast通知
function showToast(message, type = 'success') {
const bgClass = type === 'success' ? 'bg-success' : 'bg-danger';
const toast = `
<div class="toast ${bgClass} text-white" role="alert">
<div class="toast-header">
<strong class="me-auto">通知</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast"></button>
</div>
<div class="toast-body">${message}</div>
</div>
`;
$('#toastContainer').append(toast);
const toastElement = $(toast);
const toastObj = new bootstrap.Toast(toastElement[0]);
toastObj.show();
// 自动移除
setTimeout(() => {
toastElement.remove();
}, 3000);
}
</script>
</body>
</html>
使用说明
部署步骤:
- 创建数据库
config_demo - 导入SQL文件创建数据表
- 上传所有PHP文件到服务器
- 修改
config.php中的数据库连接信息 - 通过浏览器访问
index.php
功能特点:
- ✅ 支持多种配置类型(文本、多行文本、数字、下拉选择、复选框、JSON)
- ✅ 分组管理配置
- ✅ 实时保存编辑
- ✅ 删除和添加配置
- ✅ 响应式界面
- ✅ 中文界面
- ✅ Toast通知
- ✅ 数据验证
这个后台系统可以方便地管理网站的各种配置项,并且易于扩展和定制!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播