← 返回首页

技术改造经验:评论系统、私有文章、主页改版与缓存排查

这篇是本次给这个博客做技术升级的完整记录,涵盖功能实现、技术细节、部署方式与踩坑经验,也方便自己以后回顾。

一、项目背景

站点是一个轻量的 PHP + SQLite(PDO)技术博客,部署在服务器 118.24.135.158,站点目录为 /var/www/html/boke,域名根直接被 nginx 映射到该目录。无 JS 框架,模板直接由 PHP 渲染,样式集中在 assets/style.css。

这次做了一系列改造,核心原则只有一个:

新增功能绝不能干涉原有博客的正常功能,并且每次改动都必须可回退。

二、本次改造清单

  1. 评论系统(游客免注册即可评论)
  2. 仅博主可见的文章(收藏/草稿性质的内容)
  3. ip.php 的 AS 号 / 国家反查网段
  4. 主页两栏改版 + 移动端适配(汉堡抽屉导航)
  5. 排查并修复 Edge 显示旧版式的问题

三、评论系统

需求

  • 游客不用注册就能评论。
  • 评论中显示该条评论的 IP、城市、时间。
  • 同一个 IP + 同一浏览器 User-Agent + 同一篇文章,一天最多 3 条。

实现

新增 comments 表:
SQL
comments(post_id, content, ip, ua_hash, city, created_at)
  • ip:记录评论者 IP。
  • ua_hash:对 User-Agent 取哈希,用于"同 IP + 同浏览器"的判定(不直接存明文 UA,避免冗余与隐私问题)。
  • city:评论时调用 lib/ipdb 解析 IP 归属城市。
  • created_at:记录时间。
在 database.php 封装了 comment_create()、comment_list()、comment_remaining_today() 等函数。限流逻辑统计"当天该 IP+UA+帖子"的评论数,达到 3 条即提示并拒绝。

后台新增 admin/comments.php,可在导航栏进入,查看/删除评论。

四、仅博主可见文章

需求

  • 博主在编辑文章时可勾选"仅博主可见"。
  • 设置后,游客不可见(主页、分类、搜索、标签、RSS、计数均隐藏,直接访问也返回 404)。
  • 博主登录前台后可见,并显示一个徽标。

实现

复用已有的 is_sticky 机制,在 posts 表新增 is_private 字段。前台用一个探测会话的函数 blog_is_logged_in() 判断当前是否博主,在列表侧统一加 COALESCE(is_private,0)=0 过滤,游客一律看不到私密文章,只有博主本人可见。

五、ip.php 反查网段

原 ip.php 支持 IP 归属查询。本次新增:

  • 用 AS 号反查所属网段;
  • 用国家反查对应网段;
  • 查询结果支持一键复制,并带分页。
相关函数集中在 lib/ipdb.php(新增 8 个函数),原 IP 归属查询功能完整保留。

六、主页两栏改版与移动端适配

桌面端(≥992px)

改为两栏布局:左侧文章列表(约 3/4 宽),右侧固定侧边栏(关于博主 / 热门文章 / 分类统计 / 标签云 / RSS)。用 CSS Grid 实现:
CSS
.two-col {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 300px;
    gap: 28px;
}

文章卡片增强了三处:显示评论数、预计阅读时长(按字符数估算:ceil(字数 / 350))、标题 hover、摘要两行裁剪。阅读时长与评论数都用一次性聚合查询拿到(按 post_id 分组),避免逐条 N+1。

Hero 区把原来单一的文章数,换成"文章 / 分类 / 标签"三个统计小胶囊,仍然保留心情与筛选提示。

移动端(≤768px)

  • 顶栏增加汉堡按钮,点击弹出右侧抽屉导航(全部链接与分类下拉保留),点链接或遮罩或窗口变宽自动收起。
  • 侧边栏移到文章列表下方,主列表变单栏。
  • Footer 改为多栏(站点简介 + 快速导航 + 版权信息)。
变体只在追加的新样式里做,不改原 CSS 的既有规则,最大限度降低回归风险。

七、踩坑:Edge 一直显示旧版式

现象

Chrome 打开是新版式,Edge 却是旧版式。

原因

CSS 链接固定为 assets/style.css,没有版本参数。Edge 缓存了旧 style.css,拿到新 HTML(.two-col/.sidebar 已存在)后却还在用旧样式,渲染出来就像旧版式(单栏堆叠)。

解决

  1. 给 CSS 链接自动加版本号:用文件修改时间做查询串:
PHP
$cssVer = @filemtime(__DIR__ . '/../assets/style.css');
$cssHref = base_path . '/assets/style.css' . ($cssVer ? '?ver=' . $cssVer : '');
  1. 前台页面发送不缓存响应头:
PHP
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Expires: 0');

这样任何浏览器(尤其 Edge)都会强制重新验证,样式只要一变就必然重新下载。教训:给静态资源带版本号或内容指纹,是避免"新旧混用"的基本功。

八、部署与回退

所有远程改动都通过 SSH(paramiko)上传,并遵循项目约定的备份习惯:

  • 改动前先 cp 一份,命名 原文件.pre-layout-YYYYMMDD、.pre-devlog-YYYYMMDD 等。
  • 每个 PHP 文件上传后立即 php -l 校验语法。
  • 数据库改动前先备份 blog.db.pre-<feature>-<date>。
回退只需把备份覆盖回原文件即可。我会继续遵循"能不破坏旧功能就不破坏"的原则推进。

结语

一次完整的博客改造,从后端数据库设计(评论、私有文章)到前端布局(两栏 / 响应式 / 抽屉)再到运维细节(缓存、部署、回退),每一环都值得记录。希望这篇经验对你也有参考价值。

💬 评论 (0)

今日还可评论 3 条

还没有评论,来抢沙发吧。