本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:备忘md/_session_summary.md。
SoSite V3.5 — 完整会话总结
生成日期:2026-06-26
目的:用于开启新对话时快速恢复上下文
一、项目概览
SoSite — 自研轻量 PHP 社区系统(类似简化版 Discuz!),默认 SQLite 数据库,支持 MySQL。
- 版本:V3.5.0
- 根目录:
D:\phpstudy_pro\WWW\ - 架构:自制轻量 MVC 框架(非 Composer,纯手写 Autoloader)
- 索引页:
index.php→app/init.php→ Router 分发 - 启动文件:
config.php(Session 配置、数据库路径、常量) - 数据库文件:
protected/forum.db(SQLite,另含备份)
二、核心架构
目录结构(关键部分)
WWW/
├── index.php # 前端控制器(路由分发)
├── config.php # 全局配置(Session/DB/常量)
├── .htaccess / web.config # URL 重写
├── app/
│ ├── init.php # 应用初始化(autoloader→config→session→view→plugin)
│ ├── Core/
│ │ ├── Autoloader.php # PSR-4 风格自动加载
│ │ ├── Router.php # 路由引擎(支持 {param} 占位符)
│ │ ├── Controller.php # 基础控制器
│ │ ├── Model.php # 基础模型
│ │ ├── Database.php # PDO 封装(SQLite/MySQL)
│ │ └── View.php / TemplateCompiler.php # 模板引擎
│ ├── Controllers/ # 控制器
│ │ ├── Admin/ # 后台控制器(~15个)
│ │ └── *Controller.php # 前台控制器(~13个)
│ ├── Helpers/ # 辅助类(~13个)
│ ├── Models/ # 模型(~17个)
│ └── Views/ # 视图(~45个)
├── assets/ # 静态资源(CSS/JS/图片/上传)
├── plugins/ # 插件目录
├── protected/ # 保护目录(DB/缓存/Session)
├── plug/ # 插件在线生成器(独立子程序)
├── docs/ # 离线文档(17个HTML页面)
└── sositeV3.5/ # 发布包目录插件系统
- 设计:"钩子即文件"(借鉴 XiunoBBS)
- 核心文件:
app/Helpers/Plugin.php - 共 17 个钩子点:
init_after,route_register,admin_route_register,route_before_dispatch,route_after_dispatch,auth_login_after,auth_register_after,thread_create_after,post_create_after,controller_view_before,layout_head_end,nav_main_links,nav_plugin_links,nav_user_menu_items,admin_sidebar_links,home_sidebar_bottom,layout_footer - 钩子文件按需 include,可直接访问调用处作用域变量
- 缓存机制:
plugins/plugins_cache.php
已确认缺失的钩子点(需要新增)
auth_login_form_end— 登录表单底部(用于密码找回等)- 新增时需要在:
app/Views/auth/login.php密码框后添加一行Plugin::hook('auth_login_form_end')
三、会话历史里程碑
阶段 1:插件生成器开发(plug/ 目录)
用户要求开发一个在线生成 SoSite 插件的独立程序。
- 位置:
D:\phpstudy_pro\WWW\plug/ - 技术栈:PHP + SQLite(单入口,独立于主程序)
- 入口:
index.php(路由分发:?action=login|register|edit|delete|import|download|help|default) - 核心逻辑:
app/lib.php - 样式:
style.css - 数据库:
protected/plug.db - 数据库表:
users,generations
功能演进(用户逐次要求):
| # | 要求 | 最终实现 |
|---|---|---|
| 1 | 注册 + 登录 | 表单验证、BCrypt 密码哈希、Session 认证 |
| 2 | 导航栏 + 使用说明 | 顶部导航 + /docs/index.html 链接 + 帮助页 |
| 3 | 生成历史 | 列表展示、编辑(回填表单)、删除 |
| 4 | 预览/编辑器 | 在线代码编辑器 + 语法高亮(透明 textarea 覆盖 + 着色层 + 行号) |
| 5 | 模板预设 | 每日签到、友情链接、帖子收藏、SEO 优化、统计看板 |
| 6 | ZIP 导入 | 解析已有插件 ZIP 回填表单 |
| 7 | 历史搜索 | 按名称过滤 |
| 8 | 打包下载 | ZIP 打包 + 浏览器下载 |
| 9 | 宽屏 1200px | 约束宽度对齐顶部导航栏 |
阶段 2:安全加固(plug/)
第三方安全审计 → 用户要求修复,经历了两轮深度加固:
第一轮修复(7 项)
| 问题 | 严重性 | 修复 |
|---|---|---|
RCE 路径穿越 — $_POST['file'] 无过滤直接写 ZIP | 高危 | 新增 validateFilePath():禁止 .. \,只允许 [a-zA-Z0-9_/.],必须插件目录开头 |
IDOR 越权编辑 — edit_id 存 Session 致多标签页覆盖 | 高危 | 改为 <input type="hidden" name="edit_id"> 表单隐藏域,SQL 同时校验 id 和 user_id |
| Zip Slip/Bomb — 导入 ZIP 无限制 | 高危 | 限制 ZIP ≤10MB、文件数 ≤100,importPluginFromZip() 前检查 filesize() |
| 骨架代码在注释中 — 生成的 hook 文件是空注释 | 高 | $skeleton 移出注释变为可执行 PHP |
Session 固定攻击 — 登录后未 session_regenerate_id() | 中 | login() 成功调用 session_regenerate_id(true) |
命名空间硬编码 — 骨架写死 Plugin\MyPlugin | 中 | 接收 $nameSpace 参数动态生成 |
Session 大数组残留 — $_SESSION['last_gen_files'] 存全量代码 | 中 | 去掉 Session 存储,下载无 POST 则重新生成 |
第二轮修复(3 项 + CSS)
| 问题 | 修复 |
|---|---|
ZIP 导入污染 $_POST — 脏数据回填表单可被再次提交 | 改用独立 $imported 参数传入 showDashboard(),仅当前请求有效 |
| 钩子白名单缺失 — 导入的钩子未过滤 | 三重拦截:①导入时 array_intersect ②生成 POST 时过滤 ③saveGeneration/updateGeneration 同样过滤 |
下载后 unset($_SESSION['last_gen']) — 连续点击/刷新被重定向 | 删除 unset(),last_gen 只存元数据,体积极小 |
initDB() try-catch 刷日志 — 每次请求执行注定失败的 ALTER | 改 PRAGMA table_info(generations) 检测列是否存在 |
mkdir(0755) 临时目录权限过大 — 共享主机旁站提权 | 改 mkdir($dir, 0700, true) |
| Session 安全配置 | cookie_httponly=1, use_only_cookies=1, 自动检测 HTTPS 启用 cookie_secure |
CSS 变量化(用户主动做的审查优化)
- 新增 9 个 CSS 变量:
--bg-surface,--bg-code,--bg-code-gutter,--border-code,--border-code-inner,--text-code,--text-code-dim,--scrollbar-track/thumb/thumb-hover - 所有硬编码颜色替换为变量
- 钩子
:has(input:checked)选中态 - 自定义暗色滚动条
- 响应式 Grid:
repeat(auto-fit, minmax(280px, 1fr))
阶段 3:内容采集
用户要求采集其他网站内容导入本地数据库:
- https://www.52pojie.cn/forum-16-1.html — 采集 39 条(Discuz! X3.x 架构,反爬严格,从第 2 页开始避开限制)
- https://www.chinaz.com/news/ — 采集 17 条(无限制,内容在
div.pcontent > p)
数据库现状:threads 表共 98 条帖子,精品专区(category_id=4)71 条(含导入数据)
字段注意:threads.last_reply_at 曾为空字符串导致不显示在最新列表 → 修复 SQL:
UPDATE threads SET last_reply_at = created_at WHERE last_reply_at IS NULL OR last_reply_at = ''阶段 4:文档更新
- docs/ 下共 17 个 HTML 文件,54 处
V3.0.0→V3.5.0 - 页脚抽取为独立文件:
docs/_footer.html+docs/footer.js - 根据 V3.5 功能更新所有文档内容(含插件系统章节)
阶段 5:第三方核心文件审查
- 第三方的建议以
code-review-todo.md备忘,最终结论: - 3-6 条修改难度大、必要性不高 → 决定不修改
- 安全补丁(3 个点)已打进
sositeV3.5/install.php
四、用户偏好与提示
交流风格
- 全程中文
- 技术问题直接,不拖泥带水
- 不喜欢未授权修改 — 必须先问再改("我让你先看一下,不要轻易修改代码")
- 要求简洁回答,不要长篇大论
- 喜欢分点、分模块的清晰结构
用户角色
- 个人开发者/站长
- 熟悉 PHP,但有安全审计盲区
- 希望项目达到上线标准
- 重视安全 > 功能 > 美观
五、当前项目状态
已完成功能矩阵
| 模块 | 状态 | 说明 |
|---|---|---|
| 用户系统 | ✅ | 注册/登录/个人资料/等级/权限 |
| 论坛 | ✅ | 版块分类/发帖/回帖/编辑 |
| 博客 | ✅ | 文章发布/管理/分类 |
| 后台管理 | ✅ | 用户/版块/帖子/标签/等级/数据库/回收站/维护/主题 |
| 插件系统 | ✅ | 17 个钩子/后台管理/启用禁用 |
| 插件生成器 | ✅ | 独立程序,在线生成/编辑/预览/打包/导入/历史管理 |
| 文档 | ✅ | 17 页离线文档,含使用说明 |
| 安装程序 | ✅ | sositeV3.5/install.php(含安全锁、WAL 清理) |
| 发布包 | ✅ | sositeV3.5/ 和 sositeV3.5.zip(294 文件 59 目录) |
软肋 / 缺失功能
| 缺失项 | 能否插件实现 | 关键障碍 |
|---|---|---|
| 通知系统 | ✅ 完全可以 | 无,post_create_after + nav_user_menu_items 即可 |
| 密码找回 | ✅ 95% | 登录页缺 auth_login_form_end 钩子点,需改一行 core |
| 邮箱验证 | ⚠️ 可插件 | 需自行实现邮件发送 |
| 公开用户主页 | ❌ 需改 core | 缺少对应的路由和视图钩子 |
| SEO 优化 | ✅ 可插件 | layout_head_end 注入 Meta |
| 富文本编辑器 | ✅ 可插件 | 但需替换前端编辑器 |
| 响应式/移动端 | ✅ 已有基础 | 当前有 @media (max-width: 768px) 支持 |
已知配置问题
SOSITE_VERSION常量仍定义为'V3.0.0'(config.php第 3 行)config.php中define('DB_PATH', __DIR__ . '/protected/forum.db');— 数据库文件在 web 可访问目录内,生产环境需通过 web.config 或 Nginx 配置禁止*.db下载- 插件系统
Plugin::hook()通过extract($params)传递变量,钩子文件内可能产生变量名冲突
六、下一步建议(按优先级排序)
P0 — 生产部署必需
- 禁止 .db 文件直接访问 — 在 web.config 或 .htaccess 中添加
*.db拦截规则 - 关闭 display_errors —
php.ini中display_errors = Off,log_errors = On - 配置 HTTPS — 否则 Session Cookie 明文传输(config.php 已有
cookie_secure自动检测)
P1 — 建议近期实现
- 通知系统(插件) —
post_create_after钩子触发,route_register注册/notifications路由,nav_user_menu_items加铃铛图标。纯插件,0 改核心 - 密码找回(插件 + 改一行 core) — 需在
app/Views/auth/login.php密码输入框后加一行Plugin::hook('auth_login_form_end'),插件实现"忘记密码"页面、令牌校验、邮件发送 SOSITE_VERSION常量更新 —config.php中'V3.0.0'→'V3.5.0'
P2 — 长期考虑
- 公开用户主页 — 展示用户的帖子/回帖列表
- API 接口 — 为小程序或 App 预留
- 数据库自动备份 — 后台添加一键备份入口
- 错误日志系统 — 统一异常捕获和记录
- 富文本编辑器支持 — 降低普通用户门槛
用户明确表态过的决定
- "那就不改了" — 第三方建议中 3-6 条(核心文件重构)因难度大、必要性不高,已放弃
- 插件生成器的安全补丁、IDOR 修复、Zip Slip 防护 — 已全部采纳并应用
- 不修改核心代码 → 功能优先通过插件实现
七、关键文件路径速查
| 用途 | 路径 |
|---|---|
| 前端控制器 | D:\phpstudy_pro\WWW\index.php |
| 全局配置 | D:\phpstudy_pro\WWW\config.php |
| 应用初始化 | D:\phpstudy_pro\WWW\app\init.php |
| 路由引擎 | D:\phpstudy_pro\WWW\app\Core\Router.php |
| 数据库 | D:\phpstudy_pro\WWW\protected\forum.db |
| 插件系统 | D:\phpstudy_pro\WWW\app\Helpers\Plugin.php |
| 插件生成器入口 | D:\phpstudy_pro\WWW\plug\index.php |
| 插件生成器核心逻辑 | D:\phpstudy_pro\WWW\plug\app\lib.php |
| 插件生成器样式 | D:\phpstudy_pro\WWW\plug\style.css |
| 安装程序 | D:\phpstudy_pro\WWW\sositeV3.5\install.php |
| 离线文档 | D:\phpstudy_pro\WWW\docs\*.html |
| 第三方审查备忘 | D:\phpstudy_pro\WWW\code-review-todo.md |
| Session 存储路径 | D:\phpstudy_pro\WWW\protected\sessions\ |