本文由 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-20 | Alpine + htmx 改造试点 | 约 30 个文件改造;删除 5 个零散 JS |
二、逐日纪要
07-01 安全整改攻坚 + 用户组权限系统
做了什么
- 全项目代码审查(Controllers / Core / Helpers / Models / JS),产出《安全审查备忘.md》(约 26KB)与《安全修复计划.md》(约 15KB)。
- 四轮安全修复全部完成:
- 第一轮 🔴 致命 6 项:
Admin/ThemeController.phpZIP 解压 RCE(后缀白名单 + 覆盖清理)、Upload.php黑名单改白名单、Plugin.phprealpath 文件包含防护、ApiController.phpSSRF(DNS 解析 + 私有网段过滤)、User.php事务保护 + 递归修复、Search.php移除业务请求中的 DDL。 - 第二轮 🟠 高危 9 项:
Admin/BaseController.php二次验证超时 + strpos 改 parse_url、管理员自降级保护(Admin/UserController.php)、后台 POST 补 CSRF(BlogController/CategoryController)、前台文件删除加 basename、editor.jsquote DOM-XSS 转义等(vote.js、logout、DatabaseController、Vote.php 复查后确认无需改动)。 - 第三轮 🟡 重要 8 项:
Setting.php$qc未定义变量改key、Content.phpBase64 盲猜加二次校验、Settings.php文件写 LOCK_EX、Points.phpLIMIT 强转拼接、附件清理加 24 小时缓冲防误伤等。 - 第四轮 🟢 建议 5 项:
Model.phpsanitizeOrderBy去反引号、Controller.php开放重定向防护、Theme.php正则\r修复、Plugin.php5 处 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;buildWherekey 加preg_match校验;PDO 异常封装为RuntimeException;Plugin::hook()包 try-catch;Session 精简(不再写 role/username)。 - 邮箱找回密码完整链路:
Mailer.phpSMTP 类(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-rowflex,移动端恢复堆叠);.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)、SQLitedatetime('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-3gap 换行、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.phpCSP 加'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元素不显示 → CSSdisplay:none权重高于 Alpine 内联样式,改用:class在父容器绑定;③$refs.navLinksundefined →x-data与x-ref在兄弟元素,移到共同父元素;④ 投票图标消失 → 项目用 Unicode 字符实体()而非 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(拟定),主线是四件事,一环扣一环:
- 安全整改(07-01 → 07-02 下半场):先用 4 轮全项目扫描修掉 30+ 项漏洞,再对 9 个核心文件深审又修 32 项。最大成果是权限模型定型——
isAdmin()以数据库role+group_id=4为唯一可信源,用户组/版块权限从零设计到全链路过滤(发帖、浏览、回复、搜索、标签、个人中心)落地;顺带补上找回密码、邮箱验证、SMTP 后台配置,把账户体系补完整。 - SQL 一致性迁移(07-03 成计划):针对 Controller 100+ 处
$db->直连制定「不改功能只搬家」的三阶段收编计划(16 个文件、6-10 天),与 07-16 的 SQLite 残留清理、dev_docs 删除同属为 V4 清技术债。 - 二级目录部署改造(07-15):用
BASE_PATH一个常量贯穿 Router/Controller/TemplateCompiler/init——路由匹配先剥离、资源输出再拼接、后台可配置,解决「站点不装在根目录」的部署形态;代价是 admin 视图批量替换翻车,沉淀出完整改造方法论。 - Alpine + htmx 改造试点(07-20):尽管 07-16 还判定「htmx 收益不高」,本月末仍作前端现代化试点:约 30 个文件把 confirm、全选、Tab、导航、投票、签到等零散 JS 清零,删 5 个旧 JS 文件;CSP 与作用域成为新课题。
串联逻辑:安全整改立规矩 → SQL 收编清债务 → 二级目录定部署 → 前端改造提体验。每一步踩的坑都写进了方法论(见下节),这是七月比功能本身更值钱的产出。
四、经验与教训
主要从《二级目录改造_总结与教训》及 07-15、07-20 两次翻车实录提炼:
- 绝不用 search_replace 批量替换改 PHP 模板。PHP 模板里
<?php与 HTML 大量嵌套,无差别替换必破坏结构。每个文件必须 read_file 后 edit_file 单独改。 - 改错了不要写 fix 脚本补救。fix 脚本副作用不可预见,多个叠加后文件状态彻底失控。正确做法:从备份恢复原始文件 → 用 edit_file 重改。(07-15 admin 20 个文件实证;07-20 正则替换丢
$el是同型二次踩坑。) - 一个文件一个文件来,改完立即
php -l验证语法,确认无误再动下一个。 - 硬编码 URL 替换规则:
href/action→<?php echo $this->url('...'); ?>,src/script→$this->asset('...');URL 中含 PHP 表达式时整体拼进url()(如url('/thread/' . $tid)),绝不允许嵌套 PHP 标签。 - 文件修改优先级:核心(Router/Controller/TemplateCompiler/config/init)→ 默认主题视图 → 其他主题 → 插件 → JS。
- 配置只改 config.php 的
BASE_PATH,后台「站点部署路径」可覆盖,其他配置文件不动。 - 部署三件套:清 Opcache(后台维护工具)、Ctrl+F5(CSS/CSP 缓存)、改动过钩子的插件重新启用。
- 安全架构共识:权限以数据库为唯一可信源;一切外部输入(URL/IP/文件名/SQL key)白名单化;IDOR 靠循环内二次校验防御;多步写操作用事务包住。
- CSP 是双刃剑:
'unsafe-inline'保内联 onclick,'unsafe-eval'保 Alpine;前端显隐改造还要防样式表display:none与x-show的权重冲突。 - 需求决策留痕:07-16「htmx 收益不高」与 07-20「仍做试点」看似矛盾,如实记录反转过程,比强行一致对后续更有参考价值。