这份文档面向二次开发者、插件作者、主题作者和维护人员。它说明灯塔 CMS 的目录结构、请求生命周期、核心模块、数据库迁移、插件运行时、主题区块、安全边界和常见扩展方式。
技术定位
纯 PHP MVC + SQLite3,不依赖 Composer 包,部署体验接近传统 PHP 网站。
扩展重点
插件 Manifest 与 Plugin API 是首选扩展面;控制器、模型、迁移和主题模板用于核心开发。
本文档按 灯塔 CMS v1.3.4 编写。当前源码包含 22 个迁移文件、完整的 Plugin API 1.0、4 种商品价格模式和基于 Google Translate 的 249 种语言能力。
技术栈
| 层次 | 技术 | 说明 |
|---|---|---|
| 后端 | PHP 8.1+ | 纯 PHP 实现,不依赖 Composer。 |
| 数据库 | SQLite3 | 文件数据库,默认位于 storage/site.db,支持自动迁移。 |
| 架构 | MVC + Router | 单入口、集中路由、控制器、模型、视图分层。 |
| 前台主题 | PHP 模板 + Tailwind CDN | 默认主题使用 Tailwind 类名组织前台视觉。 |
| 后台界面 | PHP 视图 + JavaScript | 后台视图位于 app/views/admin/,脚本集中在 assets/admin/。 |
| 富文本与交互 | Jodit、SortableJS、Font Awesome | 用于富文本、拖拽排序、图标和后台编辑能力。 |
目录结构
核心目录如下:
shopagg-b2b-website/
├── index.php
├── app/
│ ├── Controllers/
│ │ ├── BaseController.php
│ │ ├── SiteController.php
│ │ └── AdminController.php
│ ├── Core/
│ │ ├── Router.php
│ │ ├── Controller.php
│ │ ├── Database.php
│ │ ├── Migrator.php
│ │ ├── AuthManager.php
│ │ ├── MediaManager.php
│ │ └── AdminNavigation.php
│ ├── Plugins/ # Plugin API 1.0 运行时
│ ├── Models/
│ │ ├── BaseModel.php
│ │ ├── Product.php
│ │ ├── PostModel.php
│ │ ├── Setting.php
│ │ ├── Inquiry.php
│ │ ├── Message.php
│ │ ├── Menu.php
│ │ ├── Slider.php
│ │ └── Updater.php
│ ├── Helpers/
│ ├── Migrations/
│ ├── views/admin/
│ └── routes.php
├── assets/
│ ├── admin/
│ └── site/
├── themes/
│ └── default/
├── storage/
│ ├── blocks/
│ ├── backups/
│ ├── logs/
│ ├── plugins/ # 已安装插件版本
│ └── site.db
├── plugin-assets/ # 对外提供的插件静态资源
├── plugin-dev/ # 本地插件开发目录
├── shopagg # 插件 CLI
├── uploads/
└── Documents/目录职责
| 目录 | 职责 | 扩展建议 |
|---|---|---|
app/Controllers | 核心前后台请求处理。 | 修改核心页面时从这里扩展;独立业务优先写插件。 |
app/Core | 路由、数据库、迁移、认证、媒体和后台导航。 | 非必要不要改核心类,优先使用 Plugin API。 |
app/Plugins | 插件运行时、Manifest、事件、服务、任务和隔离能力。 | 扩展协议由这里定义,业务插件放在 plugin-dev/ 开发。 |
app/Models | SQLite 数据访问。 | 核心新表应配套模型,不要在控制器里直接写大量 SQL。 |
app/Migrations | 核心数据库结构版本化。 | 核心表结构变更必须写迁移。 |
app/views/admin | 核心后台页面。 | 保持后台布局和组件风格一致。 |
themes/{theme} | 前台主题模板。 | 主题只处理展示和可配置区块,不应改核心数据结构。 |
storage/plugins | 已安装插件的版本化代码。 | 由插件管理器维护,不要手动覆盖活动版本。 |
plugin-assets | 启用插件公开的 CSS、JS 等静态资源。 | 由插件资产发布流程维护。 |
storage | 数据库、区块配置、备份和日志。 | 生产环境必须禁止 Web 直接访问。 |
uploads | 用户上传文件。 | 通过媒体库和 asset_url() 访问。 |
请求生命周期
一次前台产品详情请求的大致流程如下:
GET /product/stainless-steel-pipe
-> Web 服务器重写到 index.php
-> index.php 定义常量、启动 Session、注册自动加载
-> 加载 app/Helpers/Helpers.php
-> Database::getInstance()
-> Migrator 执行待处理迁移
-> 加载 app/routes.php
-> Router 匹配 /product/:slug
-> SiteController::productDetail($slug)
-> Product::getBySlug($slug)
-> BaseController::renderSite()
-> 加载 themes/{theme}/functions.php
-> 渲染 product_detail.php后台请求与前台类似,但会先经过认证和权限检查。未登录用户访问 /admin/* 会被重定向到登录页;员工账号只能进入被授权的模块。
核心模块
入口文件 index.php
入口文件负责:
- 定义
APP_ROOT、APP_VERSION、APP_BASE_PATH等常量。 - 设置错误处理和安全响应头。
- 启动 Session。
- 注册
App\命名空间自动加载。 - 加载全局辅助函数。
- 初始化数据库连接并触发迁移。
- 加载路由表并分发请求。
APP_VERSION 是后台更新和资源版本号的统一来源。当前源码版本为 1.3.4。
路由系统 Router
路由集中注册在 app/routes.php。前台、后台、媒体、主题、区块、菜单、轮播、更新、robots 和 sitemap 都在这里定义。
$router->add('GET', '/', [SiteController::class, 'home']);
$router->add('GET', '/product/:slug', [SiteController::class, 'productDetail']);
$router->add('POST', '/contact', [SiteController::class, 'contact']);
$router->add('GET', '/admin/products', [AdminController::class, 'products']);路由扩展建议:
- 前台展示页面放在
SiteController。 - 后台管理页面放在
AdminController。 - POST 路由必须检查 CSRF。
- 需要权限控制的后台功能必须走
AuthManager。 - 不要把业务逻辑写在
routes.php里。
数据库层 Database
Database 是 SQLite 单例连接入口。系统初始化数据库时会:
- 创建或打开
storage/site.db。 - 设置 SQLite 运行参数。
- 确保迁移表存在。
- 执行待处理迁移。
生产环境建议:
storage/site.db文件权限控制在 Web 用户可读写范围内。- 配合 Web 服务器规则禁止下载数据库文件。
- 定期备份数据库文件。
迁移系统 Migrator
迁移文件放在 app/Migrations/,按时间戳顺序执行。每个迁移只执行一次,执行记录写入 migrations 表。
return new class {
public function up(SQLite3 $db): void
{
$db->exec('CREATE TABLE IF NOT EXISTS faqs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
question TEXT NOT NULL,
answer TEXT NOT NULL,
sort_order INTEGER DEFAULT 0,
created_at TEXT NOT NULL
)');
}
public function down(SQLite3 $db): void
{
$db->exec('DROP TABLE IF EXISTS faqs');
}
};
迁移命名规范:
YYYYMMDDHHMMSS_description.php
20260731000000_add_product_price_range_fields.php控制器层
控制器层分为三层:
| 类 | 职责 |
|---|---|
Controller | 基础渲染、JSON 输出、跳转。 |
BaseController | 前台公共数据加载,读取站点设置和当前主题。 |
SiteController | 前台页面、产品、文章、案例、页面、询盘和 sitemap。 |
AdminController | 后台全部管理功能。 |
建议把数据读写交给模型,把请求参数整理和业务协调放在控制器,把 HTML 输出放在视图或主题模板。
模型层
所有模型继承 BaseModel,通过预处理语句访问 SQLite。模型负责封装常用查询、创建、更新、删除和列表检索。
| 模型 | 表 | 说明 |
|---|---|---|
User | users | 管理员和员工账号,包含角色与权限。 |
Setting | settings | Key-Value 配置,包含 site_currency 全局货币。 |
Product | products、product_prices、product_skus | 产品、阶梯价格、SKU 价格。 |
PostModel | posts | 文章、案例、页面共用内容表。 |
Category | categories | 产品和内容分类。 |
Inquiry | inquiries | 产品询盘。 |
Message | messages | 联系留言。 |
Menu | menus、menu_items | 多菜单和多级菜单。 |
Slider | sliders、slider_items | 轮播图分组和轮播项。 |
Updater | update_logs | 程序更新、备份和迁移状态。 |