xBlog 是一款基于 PHP + SQLite / PostgreSQL 构建的轻量、高性能多用户博客系统。
不依赖任何框架,代码透明,路由直接映射文件路径。快速部署、易于管理、专注写作。
一、核心特性
👥 多用户体系
支持完整的用户注册、登录、个人空间功能。每个用户拥有独立头像(支持上传/恢复默认),个人主页(user.php)展示该用户发布的全部文章、评论等。后台用户管理支持角色分配(管理员/普通用户)、封禁/解封、用户名检索等操作。
多作者可同时在站点上发布内容,适合团队博客、技术社区或开放式写作平台。站内消息面板(admin/message_panel.php)支持用户相互发送私信。
🪙 X币成长等级
每次有效评论、发文、被点赞,都会获得 X币;X币累积到一定程度,等级自动提升,解锁更多站内能力。
注册用户组暂分 4 个等级:
| 等级 | 所需 X币 | 解锁能力 |
|---|---|---|
| Lv.1 | 0 起 | 评论、发消息、基础互动 |
| Lv.2 | ≥ 10 | 可编辑 / 删除自己的评论 |
| Lv.3 | ≥ 20 | 可发布文章、编辑自己的文章、管理自己的附件 |
| Lv.4 | ≥ 50 | 可删除自己的文章,成为站内高活跃用户 |
X币来源:
- 发表评论:+1 X币
- 发表文章:+2 X币
- 文章被点赞:+1 X币
具体数值与等级门槛后台「X币设置」中配置,可能随运营策略调整。
等级不只是数字,它还直接影响:
- 你能发布哪些内容
- 你能编辑 / 删除哪些内容
- 你能查看哪些“分级文章”
- 你在评论区与个人主页显示的头像徽章
你越活跃,站内能力越强,能看的内容也越多。
🏠 个人空间
用户都有自己的个人空间页面(user.php?id=用户ID)。顶部头像、用户名、在线 / 离线状态和个人简介;下方按 TAB 标签页加载展示内容。
| 标签 | 内容 | 谁能看 |
|---|---|---|
| 个人空间 | 自定义主页,支持 Markdown,最多 3000 字;没写时显示默认欢迎页 | 所有人 |
| 文章纪 | 用户发布的文章(含置顶、分类、浏览量);没有阅读权限的文章显示锁定提示 | 所有人 |
| 评论纪 | 用户发表的评论及所属文章 | 所有人 |
| 点赞纪 | 用户点赞过的文章 | 自己 |
| 相识相伴 | 登录记录(时间、IP、设备),卡片上显示注册天数;默认保留 30 天 | 自己 |
| X币纪 | X币收支流水(发文、点赞、兑换、评论、删除、管理员调整),卡片上显示余额;默认保留 24 条 | 自己 |
可以做什么:
- 编辑个人信息:修改邮箱(不能与他人重复)、性别、个人简介;点击头像上传自定义头像,或恢复默认头像;修改密码需要输入当前密码。
- 编辑个人空间主页:用户个人展示空间,用 Markdown 写自我介绍,HTML 标签会被过滤、不安全链接会被禁用。
- 发私信:登录后可在他人的个人空间给对方发私信(需「发送私信」权限,标题最多 20 字,内容最多 110 字)。
🗄️ 双数据库支持
同时兼容 PostgreSQL 和 SQLite。个人站点可直接使用 SQLite,无需安装配置数据库服务;需要更高并发或生产级可靠性时,可迁移到 PostgreSQL,反过来也一样。
提供命令行换库工具 cli_migrate.php:自动识别当前数据库,迁移前自动备份,迁移后逐表核对并自动切换配置,失败时旧库不受影响(详见「四、数据库管理」)。
💾 备份与恢复
后台网页(admin/dbms.php)和命令行(cli_dbms.php)两种方式均可使用。支持压缩备份(.sql.gz)、大文件、按表导出,SQLite 与 PostgreSQL 的备份文件可以互相导入。命令行方式可写入计划任务,实现定时备份。
⚡ 静态页面缓存
文章详情页自动生成 HTML 静态缓存文件(cache/article/*.html),降低数据库查询压力。缓存跟随文章增删改自动失效,无需人工介入维护。
🎛️ 完整后台管理
| 模块 | 功能 |
|---|---|
| 📊 仪表盘 | 博客统计 · 快捷操作 · 主机状态 · 附件概览 |
| ✉️ 消息面板 | 发送消息 · 管理消息 · 搜索消息 |
| 📝 文章管理 | 管理文章 · 撰写文章 · 搜索文章 |
| 👥 用户管理 | 管理用户 · 分配用户组 |
| 💬 评论管理 | 管理评论 · 搜索评论 |
| 🏷️ 分类标签 | 管理分类标签 |
| ⚙️ 系统配置 | 基础设置 · 用户组管理 · 权限管理 · X币设置 |
| 🗄️ 数据管理 | 导出 / 导入 数据 |
| 📁 附件管理 | 管理附件 · 导出 / 导入 |
🔌 插件扩展机制
预留 plugin/ 插件目录,功能模块独立开发,不影响核心代码。目前内置四个插件:密码块、兑换块、访问统计、天气信息。
🌓 深色/浅色主题
前台内置浅色(style-light.css)和深色(style-dark.css)两套主题,跟随系统偏好自动切换,用户也可手动切换,偏好记忆在本地。
📡 SEO 就绪
- 自动生成 RSS 订阅源(
rss.xml) - 自动生成站点地图(
sitemap.xml) - 支持
robots.txt协议
🛡️ 安全机制
- PDO 预处理,防止 SQL 注入
- 密码哈希存储(
password_hash) - 登录态 Session 管理
- 敏感配置独立存放
- 命令行工具仅限
php-cli运行,拒绝网页访问 - 数据库导入 / 迁移在单个事务中执行,失败整体回滚
二、目录结构
xBlog - PHP + PostgreSQL / PHP + SQLite 博客架构目录:
***/
├── 404.html # 404 页面
├── ajax_comment.php # AJAX 评论处理
├── ajax_like.php # AJAX 点赞处理
├── ajax_login.php # AJAX 登录处理
├── ajax_register.php # AJAX 注册处理
├── ajax_user_status.php # AJAX 文章互动状态处理
├── ajax_view.php # AJAX 文章浏览量统计处理
├── article.php # 文章详情页
├── blog.db # SQLite 数据库文件 「PostgreSQL 无此文件」
├── captcha.php # 验证码生成
├── cli_dbms.php # ▶️ 命令行 备份 / 恢复 「日常使用」
├── cli_inst.php # ▶️ 命令行 安装向导 「首次部署用」
├── cli_migrate.php # ▶️ 命令行 换库工具 「SQLite ⇄ PostgreSQL 按需使用」
├── favicon.ico # 网站 ICO
├── favicon.png # 网站 ICO
├── generate_rss.php # RSS 订阅生成脚本
├── generate_sitemap.php # 网站地图生成脚本
├── index.php # 主页
├── inst.php # ▶️ 网页 安装向导 「首次部署用 部署完成自动删除」
├── login.php # 登录页
├── logout.php # 登出
├── README.txt # 读我
├── register.php # 注册页
├── robots.txt # 搜索引擎爬虫规则
├── rss.xml # RSS 订阅
├── search.php # 搜索页 - 临时
├── sitemap.xml # 网站地图
├── unread_count.php # 未读消息数轮询接口
├── user.php # 个人中心
├── user_message.php # 个人中心 消息纪 与 私信 AJAX 接口
├── user_tab.php # 个人中心 Tab 内容 AJAX 接口
│
├── admin/ # 后台目录
│ ├── add_article.php # 添加文章
│ ├── ajax_decrypt_secret.php # 解密密码块
│ ├── api_server_stats.php # 服务器指标 API
│ ├── api_summary.php # AI 摘要 API
│ ├── articles.php # 文章管理
│ ├── attachments.php # 附件管理
│ ├── avatar_delete.php # 头像恢复 API
│ ├── avatar_upload.php # 头像上传 API
│ ├── backup_site.php # 备份站点文件
│ ├── categories_tags.php # 分类标签管理
│ ├── check_username.php # 站内消息用户名验证接口
│ ├── comments.php # 评论管理
│ ├── config.php # 配置管理
│ ├── dbms.php # ▶️ 网页 后台 备份 / 恢复 「日常使用」
│ ├── edit_article.php # 编辑文章
│ ├── edit_comment.php # 编辑评论处理
│ ├── index.php # 后台主页
│ ├── message_panel.php # 消息管理
│ ├── search_articles.php # 文章搜索 API
│ ├── search_comments.php # 评论搜索 API
│ ├── search_message.php # 消息搜索 API
│ ├── search_users.php # 用户搜索 API
│ ├── upload.php # 上传文件
│ └── users.php # 用户管理
│
├── assets/ # 静态资源目录
│ ├── tippy/ # 提示框
│ │ ├── popper.min.js # Popper.js 库压缩版
│ │ ├── scale.css # 缩放动画样式
│ │ └── tippy-bundle.umd.min.js # 核心功能及常用插件
│ ├── admin_articles_search.js # 后台文章搜索脚本 JavaScript
│ ├── admin_comments_search.js # 后台评论搜索脚本 JavaScript
│ ├── admin_icons.svg # 后台 SVG Sprite
│ ├── admin_message_search.js # 后台消息搜索脚本 JavaScript
│ ├── admin_script.js # 后台主体脚本 JavaScript
│ ├── admin_style.css # 后台浅色主题样式
│ ├── admin_style-dark.css # 后台深色主题样式
│ ├── admin_users_search.js # 后台用户搜索脚本 JavaScript
│ ├── favicon.svg # icon
│ ├── icons.svg # 前台 SVG Sprite
│ ├── script.js # 前台主体脚本 JavaScript
│ ├── style-dark.css # 前台深色主题样式
│ ├── style-light.css # 前台浅色主题样式
│ ├── toastui-editor.min.css # Toast UI Editor 相关样式
│ ├── toastui-editor-all.min.js # Toast UI Editor 相关JS函数
│ ├── webgl-bg.js # 动态背景 主线程
│ └── webgl-bg-worker.js # 动态背景 独立线程
│
├── cache/ # 缓存目录
│ └── article/ # 文章片段缓存目录
│ └── *.html # 文章片段缓存文件
│
├── config/ # 存放敏感 / 环境相关配置
│ ├── cacert.pem # curl 使用的 CA 根证书 本地 Windows 环境需要
│ └── secrets.php # 数据库连接信息 API Key
│
├── fonts/ # 字体目录
│ └── Nunito-VariableFont_wght.woff2 # 字体文件
│
├── includes/ # 公共函数 配置 模板目录
│ ├── default/ # 默认模板目录
│ │ ├── admin_footer.php # 后台公共页脚
│ │ ├── admin_header.php # 后台公共头部
│ │ ├── footer.php # 前台公共页脚
│ │ ├── header.php # 前台公共头部
│ │ ├── index_list.php # 前台文章列表
│ │ └── user_messages_tab.php # 个人中心 消息纪 标签页内容
│ ├── admin_lists_lib.php # 后台 「列表页」 与对应 「搜索接口」 共用函数
│ ├── db_compat.php # 数据库 兼容函数 「封装 SQLite / PostgreSQL 语法差异」
│ ├── db_connect.php # 数据库 连接入口 「自动识别 SQLite / PostgreSQL」
│ ├── db_schema.php # 建表逻辑 「三个 安装 / 换库 入口共用」
│ ├── dbms_lib.php # 备份 / 恢复 核心函数 「网页版 / 命令行 共用」
│ ├── dbms_stream.php # 备份 / 恢复 核心函数 「命令行大文件 专用」
│ ├── functions.php # 公共函数
│ ├── message_lib.php # 消息公共函数库
│ └── soft_nav.php # 页面 软导航 服务端支持
│
├── plugin/ # 插件目录
│ ├── exchange_block/ # 兑换块
│ │ ├── ajax_exchange.php # AJAX 兑换接口
│ │ ├── exchange.key # 兑换块密钥文件
│ │ ├── exchange_block.php # 兑换块核心文件
│ │ ├── exchange_block_admin.css # 兑换块后台样式
│ │ ├── exchange_block_admin.js # 兑换块后台 JavaScript
│ │ ├── exchange_block_script.js # 兑换块前台 JavaScript
│ │ └── exchange_block_style.css # 兑换块前台样式
│ ├── external_link/ # 外链跳转中转
│ │ ├── external_link_script.js # 外链中转 JavaScript
│ │ └── external_link_style.css # 外链中转样式
│ ├── secret_block/ # 密码块
│ │ ├── ajax_secret.php # AJAX 密码验证接口
│ │ ├── secret.key # 密码块密钥文件
│ │ ├── secret_block.php # 密码块核心文件
│ │ ├── secret_block_admin.css # 密码块后台样式
│ │ ├── secret_block_admin.js # 密码块后台 JavaScript
│ │ ├── secret_block_script.js # 密码块前台 JavaScript
│ │ └── secret_block_style.css # 密码块前台样式
│ ├── statistics/ # 统计
│ │ ├── data/ # 数据目录
│ │ │ ├── .htaccess # 分布式配置
│ │ │ └── stats.db # 统计数据库
│ │ ├── core.php # 核心配置
│ │ ├── stats_online.php # 统计当前在线人数
│ │ ├── stats_page.php # 统计单篇文章 / 页面的浏览量
│ │ ├── stats_today.php # 统计今日访问量
│ │ ├── stats_total.php # 统计全站累计访问总量
│ │ └── tracker.php # 前端埋点接收器
│ └── weather/ # 天气
│ ├── api.php # 异步加载接口
│ ├── weather_functions.php # 天气插件函数
│ ├── weather_styles.css # 天气插件样式
│ ├── weather_widget.php # 固定地区版
│ ├── weather_widget_geolocation.php # 浏览器地理定位版
│ ├── weather_widget_ip.php # IP 定位版
│ ├── weather_widget_ip_with_days.php # IP 定位未来天气版
│ ├── weather_*.json # 固定地区版 缓存文件
│ └── weather_ip_*.json # IP 定位版 缓存文件
│
├── uploads/ # 上传目录
│ ├── images/ # 文章附件目录
│ └── avatars/ # 头像附件目录
│ ├── default/ # 默认头像附件目录
│ │ ├── male.svg # 默认男头像
│ │ └── female.svg # 默认女头像
│ └── user_*.jpg # 用户上传头像文件
│
├── vendor/ # league / commonmark 2.8.0 依赖目录
├── composer.json # 临时:项目依赖声明文件:列出需要哪些第三方库
├── composer.lock # 临时:依赖版本文件:记录当前安装的所有库的版本
└── composer.phar # 临时:Composer 工具本身:用于安装 / 更新依赖的可执行文件
三、安装部署
环境要求
| 组件 | 版本要求 |
|---|---|
| PHP | 7.4+ |
| PDO 扩展 | pgsql 或 sqlite(换库时,目标数据库对应的扩展也要启用) |
| mbstring 扩展 | 需启用(数据库导入时校验文件编码) |
| zlib 扩展 | 可选(启用后备份可压缩为 .sql.gz) |
| PostgreSQL | 12+(可选) |
| SQLite | 3(可选) |
扩展清单
| SQLite | PostgreSQL |
|---|---|
✅ mbstring - 处理多字节字符集 |
✅ mbstring - 处理多字节字符集 |
✅ curl - AI 摘要依赖 |
✅ curl - AI 摘要依赖 |
✅ gd - 验证码依赖 |
✅ gd - 验证码依赖 |
✅ openssl - 密码块插件依赖 |
✅ openssl - 密码块插件依赖 |
✅ pdo - 数据库操作基础 |
✅ pdo - 数据库操作基础 |
✅ pdo_sqlite - SQLite 数据库 |
✅ pdo_pgsql - PostgreSQL 数据库 |
✅ zip - 打包备份 |
✅ zip - 打包备份 |
部署步骤
两种方式二选一,效果相同。
inst.php(网页安装)
# 1. 上传代码至 Web 目录
# 2. 设置目录权限
# 3. 浏览器访问安装脚本 👉 https://你的域名/inst.php
# 4. 选择数据库类型,填写连接信息和管理员账号
# 5. 部署完成后自动删除 inst.php
cli_inst.php(命令行安装)
# 1. 上传代码至 Web 目录
# 2. 设置目录权限
# 3. cli 方式执行脚本 👉 php 你的目录/cli_inst.php
# 4. 选择数据库类型,填写连接信息和管理员账号
# 5. 部署完成后删除 cli_inst.php
💡 选 PostgreSQL 时,数据库需提前创建好(空库即可),安装向导只负责建表。
目录权限说明
| 路径 | 权限要求 |
|---|---|
cache/ |
可读写(生成静态缓存) |
uploads/ |
可读写(上传图片/头像) |
blog.db |
可读写(SQLite 数据库文件);其所在目录也要可写,SQLite 会在旁边生成 -wal / -shm 临时文件 |
plugin/statistics/data/ |
可读写(统计数据) |
config/ |
安装、换库时需可写(写入 / 更新 secrets.php) |
四、数据库管理
我该用哪个工具
| 我想… | 用这个 |
|---|---|
| 第一次安装 | inst.php(网页)或 cli_inst.php(命令行) |
| 日常备份 / 恢复 | 后台 admin/dbms.php,或命令行 cli_dbms.php |
| 定时自动备份 | 命令行 cli_dbms.php export,写入计划任务 |
| 把站点从 SQLite 换成 PostgreSQL(或反过来) | 命令行 cli_migrate.php |
备份与恢复
直接运行会进入菜单,按提示选择即可:
php 你的目录/cli_dbms.php
也可以带参数,适合写进计划任务:
# 查看当前数据库信息
php 你的目录/cli_dbms.php info
# 导出(--gzip 压缩;--tables=a,b 只导出指定表)
php 你的目录/cli_dbms.php export --out=/备份目录/ --gzip
# 导入(--yes 跳过确认)
php 你的目录/cli_dbms.php import /备份目录/文件.sql.gz --yes
导入方式:
| 目标数据库 | 默认方式 | 说明 |
|---|---|---|
| PostgreSQL | 合并 | 只插入 / 更新,不删除现有数据;加 --sync-delete 可删除备份里没有的行(完整还原) |
| SQLite | 整表替换 | 备份涉及的表会先清空再写入 |
💡 备份文件包含用户数据,请保存在网站目录之外。命令行默认保存到项目根目录的上一级的
xblog_backups/。
更换数据库类型(SQLite ⇄ PostgreSQL)
php 你的目录/cli_migrate.php
工具会自动识别当前数据库,只提供迁往另一种数据库的选项。
开始前:
- 在面板中停止网站(迁移期间若有人写入,新数据会丢失)
- 目标是 PostgreSQL 时,先创建好空库,并确认 PHP 已启用
pdo_pgsql
流程:
- 确认迁移前提醒,填写目标数据库信息(PostgreSQL:主机 / 端口 / 库名 / 用户 / 密码;SQLite:保存目录和文件名)
- 自动备份当前数据库
- 在目标库建表并导入数据(单个事务,失败自动回滚并清理目标库)
- 逐表核对行数,检查自增序列和触发器
- 自动切换
config/secrets.php,旧配置备份为secrets.php.bak-时间,并用站点的连接入口自检 - 可选:清理旧库(默认保留)
注意:
- 目标库已有数据时,会先列出各表行数并默认取消;选择清空时,PostgreSQL 只删除 xBlog 自己的表(不删除数据库本身,也不动其他程序的表),SQLite 文件可选择改名保留或覆盖。
- 迁移失败或中途中断,旧库和
secrets.php都不会被改动。 - 只迁移数据库,
uploads/和plugin/statistics/data/stats.db不受影响。 - 完成后在面板启动网站;若仍连着旧库,重启一次 PHP 运行环境。
secrets.php.bak-时间含数据库密码,确认无误后请删除;迁移完成后也可以删除cli_migrate.php。
出问题怎么回退:
- 旧库没清理:把
secrets.php.bak-时间还原为secrets.php即可。 - 旧库已清理:先还原
secrets.php。旧库是 SQLite,直接用cli_dbms.php导入迁移前的备份;旧库是 PostgreSQL,需要先重建表结构,再用cli_dbms.php import ... --sync-delete导入备份,较麻烦。建议迁移后先观察几天,确认一切正常再清理旧库。
五、插件详情
🔐 密码块(secret_block)
在文章内容中插入 需要密码 才能查看的隐藏片段。
- AJAX 无刷新验证
- 独立密钥管理
- 自定义提示文案
- 数据文件:
plugin/secret_block/secret.key
💱 兑换块(exchange_block)
在文章内容中插入 X币兑换 才能查看的隐藏片段。
- AJAX 无刷新验证
- 独立密钥管理
- 自定义提示文案
- 数据文件:
plugin/exchange_block/exchange.key
📊 访问统计(statistics)
独立的轻量级统计模块,数据存储于单独的 SQLite 数据库中,不影响主库性能:
- 全站累计访问量
- 今日访问量
- 当前在线人数
- 单篇文章浏览量
- 数据文件:
plugin/statistics/data/stats.db
🌤️ 天气信息(weather)
支持三种定位模式,自动缓存减少 API 调用:
| 模式 | 说明 |
|---|---|
| 固定地区版 | 手动指定城市 |
| IP 定位版 | 根据访客 IP 自动识别 |
| 浏览器定位版 | 使用 Geolocation API |