From dd957d45bd56d59372e62ad068bc9643ca75e7eb Mon Sep 17 00:00:00 2001 From: laoyang Date: Mon, 21 Sep 2026 12:56:30 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=8B=86=E5=88=86=20config.php=20?= =?UTF-8?q?=E4=B8=BA=20lib/=20=E6=A8=A1=E5=9D=97=EF=BC=8C=E6=B6=88?= =?UTF-8?q?=E9=99=A4=E9=A1=B5=E9=9D=A2=E5=B1=82=E9=87=8D=E5=A4=8D=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 纯结构性重构,不改变任何功能。 - 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 文件语法检查全部通过。 --- README.md | 12 +- add.php | 151 ++-------- cinemas.php | 47 +--- config.php | 730 ++---------------------------------------------- delete.php | 8 +- edit.php | 170 +++-------- js/main.js | 41 ++- lib/auth.php | 69 +++++ lib/db.php | 126 +++++++++ lib/helpers.php | 131 +++++++++ lib/movies.php | 196 +++++++++++++ lib/stats.php | 329 ++++++++++++++++++++++ persons.php | 14 +- 13 files changed, 1002 insertions(+), 1022 deletions(-) create mode 100644 lib/auth.php create mode 100644 lib/db.php create mode 100644 lib/helpers.php create mode 100644 lib/movies.php create mode 100644 lib/stats.php diff --git a/README.md b/README.md index ee910a7..ab45263 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,13 @@ ``` MovieLog_Server/ -├── config.php # 核心:常量、DB 连接、建表与迁移、公共函数、统计与年度报告查询 +├── config.php # 引导入口:错误报告、会话、路径常量、上传目录,并加载 lib/ 各模块 +├── lib/ # 功能模块(被 config.php 统一引入,页面无需单独 require) +│ ├── db.php # DB 连接、建表、字段与历史数据迁移、默认管理员 +│ ├── helpers.php # 输出转义、文件名、颜色校验、上传/删除文件、图片 URL +│ ├── auth.php # 登录校验、管理员账号增删改 +│ ├── movies.php # 电影/影院读取、搜索,以及表单关联数据的解析 +│ └── stats.php # 统计仪表板与年度报告查询 ├── index.php # 首页:观影列表(瀑布流)+ 快捷搜索 ├── add.php # 添加电影 ├── edit.php # 编辑电影 @@ -88,7 +94,7 @@ MovieLog_Server/ ├── fetch_movie.php # OMDb 代理接口,返回 JSON ├── test_crop.php # 开发调试页:验证 Base64 图片落盘是否正常 ├── css/style.css # 全局样式 -├── js/main.js # 少量公共脚本 +├── js/main.js # 公共脚本(含各页面共用的表单联动函数) ├── assets/.gitkeep # 静态占位资源目录 ├── db/movies.db # SQLite 数据库(运行时自动生成,不纳入版本控制) └── uploads/ # 上传图片(运行时自动生成,不纳入版本控制) @@ -98,6 +104,8 @@ MovieLog_Server/ └── avatars/ # 观影人头像 ``` +> 页面只需 `require_once 'config.php'`,`lib/` 下的模块会由引导文件统一加载,并保证依赖顺序(db → helpers → auth → movies → stats)。 + --- ## 数据库结构 diff --git a/add.php b/add.php index b02d102..32b0539 100644 --- a/add.php +++ b/add.php @@ -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; } } } + ?> @@ -470,7 +403,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { 0): ?> - + @@ -533,22 +466,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { +