[开发]SoSite 七月开发会话总结

👑Lv.11 元老 🌞 骨干会员
2026-10-23 23:52:48

本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:合并篇(见正文内 merged_from 列表)。

SoSite 七月开发会话总结

本篇由 7 篇会话总结合并去重而成(2026-07-01 ~ 07-20)。

版本线:V3.8.0 → V4.2.0(拟定);《SQL一致性迁移计划.md》作为纪要素材并入 07-03。

一、时间线总览

日期主题关键动作
07-01安全整改攻坚 + 用户组权限系统落地全项目 4 轮审查、30+ 项修复;用户组/版块权限从零实现
07-02权限收尾 + 新功能 + CSS 重构15 个文件补齐权限过滤;邀请注册插件;上传缩略图生成
07-02 下半场核心文件深审 + 找回密码/邮箱验证9 个核心文件审查、32 项修复;SMTP 后台配置
07-03前端 UI 改造 + QA 前台编辑 + 迁移计划CSRF 轮换修复;版块页重设计;SQL 一致性迁移计划成文
07-15二级目录部署改造BASE_PATH 基础设施 7 个文件;约 30 个默认视图改造;admin 视图翻车回滚
07-16图标生成器插件 + 插件系统审计13 个插件审计、12 项修复;SQLite 残留清理
07-20Alpine + htmx 改造试点约 30 个文件改造;删除 5 个零散 JS

二、逐日纪要

07-01 安全整改攻坚 + 用户组权限系统

做了什么

  • 全项目代码审查(Controllers / Core / Helpers / Models / JS),产出《安全审查备忘.md》(约 26KB)与《安全修复计划.md》(约 15KB)。
  • 四轮安全修复全部完成:
  • 第一轮 🔴 致命 6 项:Admin/ThemeController.php ZIP 解压 RCE(后缀白名单 + 覆盖清理)、Upload.php 黑名单改白名单、Plugin.php realpath 文件包含防护、ApiController.php SSRF(DNS 解析 + 私有网段过滤)、User.php 事务保护 + 递归修复、Search.php 移除业务请求中的 DDL。
  • 第二轮 🟠 高危 9 项:Admin/BaseController.php 二次验证超时 + strpos 改 parse_url、管理员自降级保护(Admin/UserController.php)、后台 POST 补 CSRF(BlogController/CategoryController)、前台文件删除加 basename、editor.js quote DOM-XSS 转义等(vote.js、logout、DatabaseController、Vote.php 复查后确认无需改动)。
  • 第三轮 🟡 重要 8 项:Setting.php $qc 未定义变量改 key、Content.php Base64 盲猜加二次校验、Settings.php 文件写 LOCK_EX、Points.php LIMIT 强转拼接、附件清理加 24 小时缓冲防误伤等。
  • 第四轮 🟢 建议 5 项:Model.php sanitizeOrderBy 去反引号、Controller.php 开放重定向防护、Theme.php 正则 \r 修复、Plugin.php 5 处 LOCK_EX。
  • 用户组 + 版块权限系统从零实现:迁移脚本 install_user_groups.php、核心类 app/Helpers/Permission.php、后台管理 Admin/GroupController.php、视图 admin/groups.php 与 admin/permissions.php;ForumController/PostController/ThreadController/HomeController 接入 SQL 层权限过滤(getAuthorizedCategoryIds()、Thread::getLatestAllowed())。
  • 其他:后台帖子/博客批量删除、帖子详情页浮动操作按钮、签到插件月份切换、发帖文件选择显示文件名;QA 插件 deactivate() 改为不删表、友情链接建表语句适配 MySQL 严格模式。
  • 故障修复 13 项:config/routes/ 路由拆分导致首页 404(恢复内联,同时移除 config/config.php 恢复根目录)、博客 $fmtMonth 残留(GROUP BY 改 DATE_FORMAT)、findByUsername 传数组、注册缺 use Settings、profile/改密码/博客删除缺 POST 路由、搜索分页计数重构、标签云改用 ID、友情链接重复(去硬编码只留钩子)、回复 500($db 未定义)等。

卡点与结论

  • 版块权限不生效(游客仍可见帖子):Permission::check() 无记录时由放行改为拒绝,getAuthorizedCategoryIds() 为空时回退全部版块并做兜底对齐。
  • 会话最后(20:30)遗留「已登录能看到帖子、未登录看不到」,修复方案已确定并实施到 Permission.php、app/Models/Thread.php、HomeController.php、ForumController.php;若上传后仍异常,疑为服务器 Opcache,需后台「维护工具」清缓存或重启 PHP-FPM。

遗留

  • 安全审查第四轮(性能优化)未全做;部署时须先跑 php install_user_groups.php,再在 phpMyAdmin 补录 category_permissions 默认数据 SQL。

07-02 权限收尾 + 新功能 + CSS 重构

做了什么

  • 用户组权限 15 个文件收尾:role/group_id 强绑定(普通用户不能越组、管理员强制 group_id=4)、PostController 发帖二次校验、Thread edit/delete 版块权限校验、搜索 FTS 结果/标签列表/个人中心动态按权限过滤(SearchController/TagsController/ProfileController)、deleteGroup 加事务 + 用户重置默认组、游客回退从全局一刀切改为版块级别(查 group=1 对应权限)、内置组(1~4)编辑限制、check() 加 $perm 白名单、修复「权限全部取消勾选不生效」(HTML 复选框不提交空值)。
  • 新功能:
  • 帖子/博客批量转移版块:Admin/ThreadController.php、Admin/BlogController.php 各新增 batch_move,配套 admin/threads.php、admin/blog_manage.php 下拉框 + JS。
  • 邀请注册插件 plugins/invite/(InviteController + 6 个钩子 + app/Controllers/AuthController.php 加一行钩子调用):积分生成邀请码 → 被邀请人填码注册 → 邀请码标记已使用。
  • 上传缩略图:Upload.php 新增 makeThumbnail()(Imagick 优先、GD 降级),jpg/jpeg/png/gif/webp 自动生成 400×300、质量 80% 的 thumb_ 缩略图,原图小于该尺寸不生成;thread/show.php 附件显示缩略图、lightbox 看原图。
  • CSS 重构:19 个视图(后台 10 + 前台 9)的内联样式提取为工具类,admin.css / components.css / forum.css 共新增 70+ 类,清理 .fw-400 定义 3 次、.input-disabled 冲突等冗余。
  • 字号样式统一:帖子/博客标题统一 16px(PC 与移动端)、博客详情页标题 32px→20px、博客正文图片限高 500px。
  • app/Core/TemplateCompiler.php 图标定义从 58 个扩展到 105 个(互动/时间/操作/标记/奖励/媒体等类别)。

遗留

  • 旧帖子批量补缩略图脚本未做(需单独 CLI 调 Upload::makeThumbnail());post_favorite、qa 等插件可能绕过权限需逐个审;role/group_id 双轨制统一属架构级改造待后续。
  • 部署注意:清 Opcache;邀请插件需进后台重新启用(钩子列表已变);浏览器 Ctrl+F5 刷 CSS 缓存。

07-02 下半场 核心深审 + 找回密码/邮箱验证

做了什么

  • 按「安全风险 + 架构核心」顺序审查 9 个核心文件(记录见《代码审查计划与方法论.md》):Permission.php(游客回退双入口不一致、check 缺边界)、Auth.php(role ↔ group_id 权限分裂,定为最严重架构问题;Session 过度信任)、Controller.php(RememberMe/在线状态位置错误)、Router.php(干净无问题)、Model.php(buildWhere 接受字符串 SQL、无 fillable)、Database.php(质量最高)、ThreadController.php(两个严重 IDOR)、PostController.php、Upload.php(Imagick RCE、GD 像素炸弹)、Content.php(style UI 劫持、id DOM Clobbering)。
  • 共 32 项修复:
  • P0 6 项:全站任意附件删除 IDOR(delete_attachments 循环内加 SELECT attachments WHERE thread_id=:tid 校验)、跨版块移帖越权(edit() 中 category_id 变更时调 Permission::canPost())、Imagick RCE(readImageBlob() + setOption('svg:auto-graphic','false'))、GD 像素炸弹 DoS(>5000 像素拦截)、从 $allowedAttrs 移除 style 和 id。
  • P1 6 项:回复接口包 begin/commit/rollback 事务、requireLogin 移到 POST 入口最前、主题颜色越权、MIME 白名单(补 webp、无映射则拒绝)、uniqid 改 bin2hex(random_bytes(16))、str_ireplace 修大小写内容截断。
  • P2 20 项(含架构级):isAdmin() 改为同时校验 role=admin + group_id=4,以数据库为唯一可信源;RememberMe/在线状态从 view() 移到 init.php(AJAX/API 也能恢复登录);redirect 白名单(仅 / 开头,//evil.com 也拦截);CSP 加 default-src 'self'; script-src 'self' 'unsafe-inline'、Permissions-Policy;requireAdmin 返回 403;buildWhere key 加 preg_match 校验;PDO 异常封装为 RuntimeException;Plugin::hook() 包 try-catch;Session 精简(不再写 role/username)。
  • 邮箱找回密码完整链路:Mailer.php SMTP 类(SSL/TLS、AUTH LOGIN、Dot-Stuffing)+ AuthController::forgotPassword()/resetPassword()/ensurePasswordResetsTable() + forgot_password.php/reset_password.php 视图 + 4 条路由 + 登录页「忘记密码?」链接。
  • 注册邮箱验证:User.php 新增 setVerifyToken()/markEmailVerified(),verifyEmail($token),未验证禁止登录,附 emails/verify_email.txt 模板。
  • 后台 SMTP 配置页:SettingsController::mailSettings() + admin/mail_settings.php 独立子页;Mailer::cfg() 优先读 settings 表、回退 config.php 常量。
  • Bug 修复 5 项:CSP 拦内联 onclick(补 'unsafe-inline')、SMTP 表单互相覆盖(拆独立子页)、key 保留字 SQL 报错(改直接 SQL 加反引号)、email_verified 列创建晚于查询(ensureEmailVerifyColumns() 移到 register() 开头)、查询用 user_id 但表字段是 id。30/30 自动化测试通过。

遗留

  • fillable 白名单需每个 Model 定义(变更面大);Base64 盲目解码需前端配合 is_base64;旧帖缩略图脚本仍未做。
  • 部署注意:清 Opcache、后台填入 SMTP 参数、Ctrl+F5(CSP 头变化)。

07-03 前端 UI 改造 + QA 前台编辑 + 迁移计划

做了什么

  • CSRF Token 轮换导致投票/回帖 403:Csrf::verify() 成功后轮换 Token,但前端 window.CSRF_TOKEN 和表单 <input name="csrf"> 未同步 → ApiController::vote() 返回 csrf_token 字段,vote.js 两处 onSuccess 回调同步更新全部 Token 与隐藏域。
  • 前端 UI 改造:
  • 分类版块页重设计(PC 表格 / 移动卡片)、去内联样式、移动端 word-break: break-all、表头跟随主题 var(--primary-color),assets/css/forum.css 大幅重构并删 .col-author、.thread-table 等旧 CSS。
  • 首页横线移除;发帖/博客分类+标题同行(.field-row flex,移动端恢复堆叠);.btn-submit 等硬编码配色改 CSS 变量。
  • 导航去「标签」移侧边栏标签云(ForumController 传 Tag::getPopular(20));标签云标题加 /tags 链接。
  • 生成 favicon.ico/favicon.svg;修复纯配色主题无 style.css 的 404(file_exists() 检测后再加载)。
  • QA 插件前台编辑:新增 GET/POST /qa/edit/{id}(route_register.php + QaController::edit()),复用 ask.php 预填;修复 JS 写死 fetch('/qa/ask') 改 fetch(this.action)、SQLite datetime('now','localtime') 不兼容 MySQL、:tid 同名参数重复、AJAX 需返回 JSON 等问题。
  • 友链 logo 优先显示(200×40);收藏页移动端修复;xiuno2 主题整体删除(assets/css/themes/xiuno2.css + assets/themes/xiuno2/)。
  • 性能:加 3 个复合索引——threads(category_id, is_pinned, last_reply_at(20))、posts(thread_id, created_at(20))、blogs(user_id, created_at(20)),写入 protected/database/init.php 并附 add_indexes.php 脚本;Session Redis 因服务器(100MB 磁盘、IIS+CGI)放弃;COUNT 缓存、模板编译、N+1 查询核查均通过。
  • CSS 架构清理(forum.css/blog.css/layout.css 冗余)+ 6 个主题 CSS 规范化 + 新增「暗夜极光 aurora_night」「暮色暖橘 sunset_warmth」两主题。
  • schema.sql/init.php 增加 createUserGroupTables():user_groups、category_permissions 建表 + 默认 4 组 + users.group_id 迁移。
  • SQL 一致性迁移计划成文(本日素材):针对 Controller 中约 100+ 处 $db->query/fetchAll/fetchOne 直连,目标「所有 SQL 统一收编 Helper,Controller 零 $db->」。三阶段共 16 个文件、预估 6-10 天:第一阶段前台收尾(新建 Forum.php,标签云/统计搬入 Settings/Tag/User.php);第二阶段 Admin 专项(UserController ~25 处最重,MaintenanceController ~12 处等 8 个);第三阶段前端收尾(4 个)。四原则:不改功能只搬家、不改 Helper 签名、一次只动一个 Controller、插件不受影响。检验标准:grep $db-> 零残留 + 页面全操作手测。

卡点与结论

  • 投票 403 的根因是「服务端轮换、前端不轮换」,修复模式为「接口回传新 Token + JS 全局同步」,表单类 403 同源同解。

遗留

  • plugins/docs_link/ 待删;版本号升 4.0 待定;线上 config.php 数据库配置待改。SQL 迁移计划仅成文,实际执行进度未记入当日纪要。

07-15 二级目录部署改造

做了什么

  • 核心基础设施 7 个文件全部完成:config.php 新增 define('BASE_PATH', '');Router::dispatch() 从 REQUEST_URI 剥离 BASE_PATH 再匹配路由;Controller::redirect() 自动拼接 BASE_PATH;TemplateCompiler 的 asset() 返回路径拼接并新增 url() 方法;app/init.php 初始化后从 settings 表读 base_path 覆盖常量;SettingsController::basic() 保存 base_path;settings_basic.php 新增「站点部署路径」输入框(后台可覆盖 config.php)。
  • 默认主题视图约 30 个文件(layouts/main、admin/_sidebar、home、forum、thread、post、auth 全部、blog 全部、search、profile、message 全部、tags、theme、invite)全部改造完成。

卡点与结论

  • admin 视图约 20 个文件用 search_replace 批量替换,嵌套 PHP 结构被破坏;连写多个 fix 脚本越修越乱,文件状态彻底失控。最终全部回滚到原始状态,不带 $this->url() 包裹,需重新逐个修改。 教训详见第四节。

遗留

  • morden 主题约 27 个文件、插件 11 个、JS(editor.js、vote.js)未开始;剩余约 60 个文件,估算 1.5-2.5 小时。

07-16 图标生成器 + 插件审计 + SQLite 清理

做了什么

  • 图标生成器插件 plugins/icon_generator/(约 4 小时会话):参考 xiunox-main 图标生成器,调研 FontAwesome 6.4.0 Free 与 Tabler Icons 3.44.0 后,决定基于自带的 FontAwesome 4.x 开发。功能:图标选择网格、背景(纯色/渐变/无)、图标颜色/大小/圆角/角标/尺寸预设、实时预览、导出 PNG/SVG、复制 SVG;代码/模板/样式分离(FrontController.php + views/generator.php + assets/style.css + assets/script.js)。修复问题:页面空白(视图路径)、资源 404($this->asset())、CSS 自包含(不依赖 Bootstrap)、FA4 不支持图标(删 crown/award/gem、修正 delete unicode)、g-3 gap 换行、TemplateCompiler 注册 bookmark 图标映射。交付上传包 chajian/tubiao/。
  • 插件系统全面审计(13 个插件逐文件审),发现:6 个残留备份文件(.bak/.revert)、5 处 BASE_PATH 未用(二级目录部署资源 404)、10 处冗余 require_once、3 处钩子内联 CSS/JS 过大、dev_docs 命名空间大小写 bug、seo 自定义头代码被转义。产出 plugins_审计报告.md。
  • 审计修复 12 项:删 6 个备份、dev_docs 命名空间、seo 转义(layout_head_end.php)、announcements/post_favorite/friend_links/invite 资源路径与 BASE_PATH、daily_checkin 登录检查、red_packet 建表逻辑(新建 init_after.php + RedPacketController.php)、edit_info SQLite 兼容(post_edit_after.php/thread_edit_after.php)、user_profile 404 处理。产出 插件修复报告.md 与 chajian/plugins/ 修复包。
  • SQLite 残留清理(12 个文件):Database.php 删 getDbType() 和 SQL 兼容替换、3 个后台 Controller 删 dbType 变量、后台视图默认值 sqlite→mysql、daily_checkin/qa 删 SQLite 分支;彻底删除 dev_docs 插件(Plugin.php 1083 行、分支多、文档过期);删 plugins_cache.php 重建缓存。产出 清除sqlite代码计划.md。

卡点与结论(关键技术决策)

  • FA4 不升级 FA6(16px 实心风格更清晰、精简够用);图标用字体方式(ctx.fillText());当时判断 htmx「论坛交互少收益不高」不建议改造;论坛/博客总开关无意义不做;dev_docs 彻底删除。

遗留

  • 插件修复包需按部署说明上线;图标生成器未做批量旧图处理。

07-20 Alpine + htmx 改造试点

做了什么

  • 引入 assets/lib/alpine.min.js(v3,约 46KB)与 assets/lib/htmx.min.js(v2,约 51KB)。核心原则:不改 CSS 类名(mn-、c-、fs-* 保留)、不改内联样式、不动 CKEditor 与 FontAwesome、不引 Tailwind、不引任何构建工具、每次改完做 PHP 语法检查。
  • 约 30 个文件改造:布局 2 个(默认 + modern 主题 layouts/main.php 导航切换 Alpine 化、修下拉菜单);app/Core/Controller.php CSP 加 'unsafe-eval';Admin 后台约 15 个(confirm 弹窗 + 全选/取消 Alpine 化,含 ThreadController 加 needsEditor => true);message 3 个;modern 主题个人中心 Tab 切换;thread/show.php(默认 + modern)confirm 删除 + 投票 htmx 化(ApiController 加 htmx HTML 片段响应、Vote::renderButtons 改 htmx 属性);骰子 dice、猜题 quiz_duel、每日签到 daily_checkin 三插件 AJAX 改 htmx;插件后台模态框/confirm 12 个。
  • 删除文件:assets/js/nav.js、assets/js/vote.js、dice/quiz_duel 的 script.js、废弃的 s-state.js/s-fetch.js。
  • 踩坑记录 6 个:① Alpine 完全无工作且控制台无报错 → CSP 缺 'unsafe-eval';② x-show 元素不显示 → CSS display:none 权重高于 Alpine 内联样式,改用 :class 在父容器绑定;③ $refs.navLinks undefined → x-data 与 x-ref 在兄弟元素,移到共同父元素;④ 投票图标消失 → 项目用 Unicode 字符实体(&#xf087;)而非 CSS 类,需统一;⑤ 个人中心 Tab 全显示 → 同样是 x-data 作用域问题;⑥ 正则批量替换把 $el.submit() 变成 .submit()($el 被当捕获组)——与 07-15 教训同型的二次踩坑。

遗留

  • 全站功能测试未跑;modern 主题 forum/category.php、默认模板 profile/index.php、QA 插件前台待确认;ziyuan 目录确认后可删。

三、七月主线

SoSite 这个月从 V3.8.0 推进到 V4.2.0(拟定),主线是四件事,一环扣一环:

  1. 安全整改(07-01 → 07-02 下半场):先用 4 轮全项目扫描修掉 30+ 项漏洞,再对 9 个核心文件深审又修 32 项。最大成果是权限模型定型——isAdmin() 以数据库 role + group_id=4 为唯一可信源,用户组/版块权限从零设计到全链路过滤(发帖、浏览、回复、搜索、标签、个人中心)落地;顺带补上找回密码、邮箱验证、SMTP 后台配置,把账户体系补完整。
  2. SQL 一致性迁移(07-03 成计划):针对 Controller 100+ 处 $db-> 直连制定「不改功能只搬家」的三阶段收编计划(16 个文件、6-10 天),与 07-16 的 SQLite 残留清理、dev_docs 删除同属为 V4 清技术债。
  3. 二级目录部署改造(07-15):用 BASE_PATH 一个常量贯穿 Router/Controller/TemplateCompiler/init——路由匹配先剥离、资源输出再拼接、后台可配置,解决「站点不装在根目录」的部署形态;代价是 admin 视图批量替换翻车,沉淀出完整改造方法论。
  4. Alpine + htmx 改造试点(07-20):尽管 07-16 还判定「htmx 收益不高」,本月末仍作前端现代化试点:约 30 个文件把 confirm、全选、Tab、导航、投票、签到等零散 JS 清零,删 5 个旧 JS 文件;CSP 与作用域成为新课题。

串联逻辑:安全整改立规矩 → SQL 收编清债务 → 二级目录定部署 → 前端改造提体验。每一步踩的坑都写进了方法论(见下节),这是七月比功能本身更值钱的产出。

四、经验与教训

主要从《二级目录改造_总结与教训》及 07-15、07-20 两次翻车实录提炼:

  1. 绝不用 search_replace 批量替换改 PHP 模板。PHP 模板里 <?php 与 HTML 大量嵌套,无差别替换必破坏结构。每个文件必须 read_file 后 edit_file 单独改。
  2. 改错了不要写 fix 脚本补救。fix 脚本副作用不可预见,多个叠加后文件状态彻底失控。正确做法:从备份恢复原始文件 → 用 edit_file 重改。(07-15 admin 20 个文件实证;07-20 正则替换丢 $el 是同型二次踩坑。)
  3. 一个文件一个文件来,改完立即 php -l 验证语法,确认无误再动下一个。
  4. 硬编码 URL 替换规则:href/action → <?php echo $this->url('...'); ?>,src/script → $this->asset('...');URL 中含 PHP 表达式时整体拼进 url()(如 url('/thread/' . $tid)),绝不允许嵌套 PHP 标签。
  5. 文件修改优先级:核心(Router/Controller/TemplateCompiler/config/init)→ 默认主题视图 → 其他主题 → 插件 → JS。
  6. 配置只改 config.php 的 BASE_PATH,后台「站点部署路径」可覆盖,其他配置文件不动。
  7. 部署三件套:清 Opcache(后台维护工具)、Ctrl+F5(CSS/CSP 缓存)、改动过钩子的插件重新启用。
  8. 安全架构共识:权限以数据库为唯一可信源;一切外部输入(URL/IP/文件名/SQL key)白名单化;IDOR 靠循环内二次校验防御;多步写操作用事务包住。
  9. CSP 是双刃剑:'unsafe-inline' 保内联 onclick,'unsafe-eval' 保 Alpine;前端显隐改造还要防样式表 display:none 与 x-show 的权重冲突。
  10. 需求决策留痕:07-16「htmx 收益不高」与 07-20「仍做试点」看似矛盾,如实记录反转过程,比强行一致对后续更有参考价值。
轻量级、高性能、零 MySQL 依赖的PHP社区系统。
| 浏览 3 次 | 回复 0 次

全部回复 (0)

暂无回复

请 登录