refactor: 拆分 config.php 为 lib/ 模块,消除页面层重复代码
纯结构性重构,不改变任何功能。 - config.php 由 739 行缩减为 42 行,改为纯引导入口;新增 ROOT_DIR 常量 统一拼接绝对路径(lib/ 内模块的 __DIR__ 会指向 lib/,必须替换) - 新增 lib/ 五个模块 db.php / helpers.php / auth.php / movies.php / stats.php, 由 config.php 按 db → helpers → auth → movies → stats 顺序加载 - add.php、edit.php 各自约 80 行重复的 POST 处理改为调用 resolveCinemaId / resolvePersonIds / linkViewers / uploadImageFile / saveBase64Image / uploadMultiplePhotos / deleteStoredFile - cinemas.php、persons.php 中重复 4 次的颜色校验改用 normalizeHexColor() - toggleNewViewer / removeViewerRow / toggleNewCinema 下沉至 js/main.js, add.php 中的 removeViewer 统一更名为 removeViewerRow - 删除死代码:imageUrl()(全项目无调用);cinemas.php 配色数组中本就会被 array_slice 丢弃的 extra 颜色逻辑,简化为单条扁平 50 元素数组 - README 目录结构补充 lib/ 说明 验证方式:以便携 PHP 8.4 搭建 A/B 回归环境,播种固定数据后遍历 47 个 GET/POST 端点录制「状态码 + 响应体」。重构前后 42 个逐字节相同、2 个仅 上传文件名时间戳不同、3 个差异均为内联脚本下沉(已单独校验函数体逐字符 等价,剥离脚本后 HTML 标记完全一致)。24 个 PHP 文件语法检查全部通过。
This commit is contained in:
@@ -23,46 +23,27 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$cinema_id = $_POST['cinema_id'] ?? '';
|
||||
$viewer_selects = $_POST['viewer_select'] ?? [];
|
||||
$viewer_news = $_POST['viewers_new'] ?? [];
|
||||
|
||||
|
||||
// 票根裁剪数据
|
||||
$ticket_crop = $_POST['ticket_crop'] ?? '';
|
||||
|
||||
// 新建电影院
|
||||
$new_cinema_place = trim($_POST['new_cinema_place'] ?? '');
|
||||
$new_cinema_name = trim($_POST['new_cinema_name'] ?? '');
|
||||
$new_cinema_address = trim($_POST['new_cinema_address'] ?? '');
|
||||
|
||||
if ($cinema_id === 'new' && !empty($new_cinema_name)) {
|
||||
$stmt = $db->prepare("INSERT INTO cinemas (place, name, address) VALUES (?, ?, ?)");
|
||||
$stmt->execute([$new_cinema_place, $new_cinema_name, $new_cinema_address]);
|
||||
$cinema_id = $db->lastInsertId();
|
||||
} elseif ($cinema_id === 'new') {
|
||||
$cinema_id = null;
|
||||
} elseif (!empty($cinema_id) && is_numeric($cinema_id)) {
|
||||
$cinema_id = (int)$cinema_id;
|
||||
} else {
|
||||
$cinema_id = null;
|
||||
}
|
||||
|
||||
|
||||
// 电影院:选择已有影院、新建影院或留空
|
||||
$cinema_id = resolveCinemaId(
|
||||
$cinema_id,
|
||||
trim($_POST['new_cinema_place'] ?? ''),
|
||||
trim($_POST['new_cinema_name'] ?? ''),
|
||||
trim($_POST['new_cinema_address'] ?? '')
|
||||
);
|
||||
|
||||
if (empty($title)) {
|
||||
$error = '请输入电影名称';
|
||||
} elseif (empty($watch_date)) {
|
||||
$error = '请选择观影日期';
|
||||
} else {
|
||||
// ----- 处理海报(直接上传) -----
|
||||
$poster_path = '';
|
||||
if (isset($_FILES['poster']) && $_FILES['poster']['error'] === UPLOAD_ERR_OK) {
|
||||
$ext = strtolower(pathinfo($_FILES['poster']['name'], PATHINFO_EXTENSION));
|
||||
if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
|
||||
$filename = uniqueFilename($_FILES['poster']['name']);
|
||||
$target = POSTER_DIR . $filename;
|
||||
if (move_uploaded_file($_FILES['poster']['tmp_name'], $target)) {
|
||||
$poster_path = 'uploads/posters/' . $filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----- 处理票根(裁剪优先) -----
|
||||
// ----- 海报:直接上传 -----
|
||||
$poster_path = uploadImageFile('poster', POSTER_DIR, 'uploads/posters/') ?? '';
|
||||
|
||||
// ----- 票根:裁剪结果优先,其次原始上传 -----
|
||||
$ticket_path = '';
|
||||
if (!empty($ticket_crop)) {
|
||||
$new_path = saveBase64Image($ticket_crop, TICKET_DIR, 'ticket');
|
||||
@@ -71,18 +52,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
} else {
|
||||
$error = '票根裁剪保存失败,请重试';
|
||||
}
|
||||
} elseif (isset($_FILES['ticket']) && $_FILES['ticket']['error'] === UPLOAD_ERR_OK) {
|
||||
$ext = strtolower(pathinfo($_FILES['ticket']['name'], PATHINFO_EXTENSION));
|
||||
if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
|
||||
$filename = uniqueFilename($_FILES['ticket']['name']);
|
||||
$target = TICKET_DIR . $filename;
|
||||
if (move_uploaded_file($_FILES['ticket']['tmp_name'], $target)) {
|
||||
$ticket_path = 'uploads/tickets/' . $filename;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ticket_path = uploadImageFile('ticket', TICKET_DIR, 'uploads/tickets/') ?? '';
|
||||
}
|
||||
|
||||
// 如果没有错误,继续
|
||||
|
||||
// 没有错误才继续
|
||||
if (empty($error)) {
|
||||
// 插入电影
|
||||
$stmt = $db->prepare("
|
||||
@@ -91,60 +65,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
");
|
||||
$stmt->execute([$title, $info, $poster_path, $ticket_path, $cinema_id, $watch_date]);
|
||||
$movie_id = $db->lastInsertId();
|
||||
|
||||
// ---- 处理合影照片(多张) ----
|
||||
if (isset($_FILES['photos']) && is_array($_FILES['photos']['tmp_name'])) {
|
||||
$photo_files = $_FILES['photos'];
|
||||
for ($i = 0; $i < count($photo_files['tmp_name']); $i++) {
|
||||
if ($photo_files['error'][$i] === UPLOAD_ERR_OK) {
|
||||
$ext = strtolower(pathinfo($photo_files['name'][$i], PATHINFO_EXTENSION));
|
||||
if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
|
||||
$filename = uniqueFilename($photo_files['name'][$i]);
|
||||
$target = PHOTO_DIR . $filename;
|
||||
if (move_uploaded_file($photo_files['tmp_name'][$i], $target)) {
|
||||
$photo_path = 'uploads/photos/' . $filename;
|
||||
$stmt2 = $db->prepare("INSERT INTO movie_photos (movie_id, photo_path) VALUES (?, ?)");
|
||||
$stmt2->execute([$movie_id, $photo_path]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---- 处理观影人 ----
|
||||
$person_ids = [];
|
||||
foreach ($viewer_selects as $idx => $val) {
|
||||
if ($val === 'new') {
|
||||
$new_name = trim($viewer_news[$idx] ?? '');
|
||||
if (!empty($new_name)) {
|
||||
$chk = $db->prepare("SELECT id FROM persons WHERE name = ?");
|
||||
$chk->execute([$new_name]);
|
||||
$existing = $chk->fetch();
|
||||
if ($existing) {
|
||||
$person_ids[] = $existing['id'];
|
||||
} else {
|
||||
$ins = $db->prepare("INSERT INTO persons (name) VALUES (?)");
|
||||
$ins->execute([$new_name]);
|
||||
$person_ids[] = $db->lastInsertId();
|
||||
}
|
||||
}
|
||||
} elseif (is_numeric($val) && $val > 0) {
|
||||
$person_ids[] = (int)$val;
|
||||
}
|
||||
}
|
||||
$person_ids = array_unique($person_ids);
|
||||
if (!empty($person_ids)) {
|
||||
$stmt = $db->prepare("INSERT INTO viewers (movie_id, person_id, name) VALUES (?, ?, ?)");
|
||||
foreach ($person_ids as $pid) {
|
||||
$stmt->execute([$movie_id, $pid, '']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---- 观影照片(多张)----
|
||||
uploadMultiplePhotos('photos', $movie_id);
|
||||
|
||||
// ---- 一起看的人 ----
|
||||
linkViewers($movie_id, resolvePersonIds($viewer_selects, $viewer_news));
|
||||
|
||||
header('Location: detail.php?id=' . $movie_id);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
@@ -470,7 +403,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
</select>
|
||||
<input type="text" name="viewers_new[]" placeholder="输入新姓名" style="flex:1;display:<?= ($val === 'new') ? 'block' : 'none' ?>;padding:8px;border:1px solid #ddd;border-radius:6px;" value="<?= h($new_name) ?>">
|
||||
<?php if ($idx > 0): ?>
|
||||
<button type="button" class="btn-remove-viewer" onclick="removeViewer(this)">×</button>
|
||||
<button type="button" class="btn-remove-viewer" onclick="removeViewerRow(this)">×</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
@@ -533,22 +466,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="js/main.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.js"></script>
|
||||
<script>
|
||||
// ---------- 观影人 ----------
|
||||
function toggleNewViewer(select) {
|
||||
var parent = select.parentElement;
|
||||
var input = parent.querySelector('input[name="viewers_new[]"]');
|
||||
if (select.value === 'new') {
|
||||
input.style.display = 'block';
|
||||
input.required = true;
|
||||
} else {
|
||||
input.style.display = 'none';
|
||||
input.required = false;
|
||||
input.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
function addViewerRow() {
|
||||
var container = document.getElementById('viewerContainer');
|
||||
var div = document.createElement('div');
|
||||
@@ -561,25 +482,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
selectHtml += '<option value="new">➕ 新增</option>';
|
||||
selectHtml += '</select>';
|
||||
var inputHtml = '<input type="text" name="viewers_new[]" placeholder="输入新姓名" style="flex:1;display:none;padding:8px;border:1px solid #ddd;border-radius:6px;">';
|
||||
var removeBtn = '<button type="button" class="btn-remove-viewer" onclick="removeViewer(this)">×</button>';
|
||||
var removeBtn = '<button type="button" class="btn-remove-viewer" onclick="removeViewerRow(this)">×</button>';
|
||||
div.innerHTML = selectHtml + inputHtml + removeBtn;
|
||||
container.appendChild(div);
|
||||
}
|
||||
|
||||
function removeViewer(btn) {
|
||||
var container = document.getElementById('viewerContainer');
|
||||
if (container.children.length > 1) {
|
||||
btn.parentElement.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- 电影院 ----------
|
||||
function toggleNewCinema() {
|
||||
var select = document.getElementById('cinemaSelect');
|
||||
var group = document.getElementById('newCinemaGroup');
|
||||
group.style.display = select.value === 'new' ? 'block' : 'none';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
toggleNewCinema();
|
||||
document.querySelectorAll('.viewer-input-group').forEach(function(group) {
|
||||
|
||||
Reference in New Issue
Block a user