Hope CMS 文档
Hope CMS(希望CMS)是一款面向中文站长的轻量开源 CMS:博客写作、主题与插件扩展、支付能力开箱可用,适合个人站、工作室站与付费资源站。
命名说明
| 名称 |
用途 |
| Hope CMS |
程序主名称(对外品牌、文档、导航) |
| 希望CMS |
中文副名称 |
功能简介
- Markdown 写作(Editor.md;分类 / 标签 / 封面 / 别名 / 置顶 / 阅读密码)
- 多用户角色(管理员 / 编辑 / 作者 / 访客)与后台模块权限
- SEO(站点 / 文章 / 分类 / 标签 TDK)与动态 / 伪静态链接
- REST API(API Key、访问限流)
- 主题切换、插件挂载点
- 媒体附件、个人媒体库与前台资源下载
- 评论审核、验证码、邮件通知
- 个人中心、余额充值、邀请奖励与在线支付(微信 / 支付宝等)
- AI 工作台与后台助手
- 备份导入、更新缓存、SMTP、多语言后台
- 统一数据库层(链式查询;插件在
callback_init 建表)
- 示例主题
default、示例插件 tips 可直接对照学习
官方官网主题还可提供:用户论坛、站内开发文档等。
适合做什么
- 个人博客 / 内容站
- 付费下载 / 会员资源站(配合 Shop 等主题)
环境一览
| 项目 |
要求 |
| PHP |
7.0+(推荐 8.0+) |
| 数据库 |
MySQL 5.6+ / MariaDB 10.3+(需 mysqli 或 pdo_mysql) |
| Web |
Apache / Nginx |
安装与配置细节见 安装指南。
文档导航
官方域名
- hopecms.cn
- www.hopecms.cn
请仅从官方域名下载安装包,其他来源存在安全风险。
软件许可证
Hope CMS(希望CMS)核心代码按 Apache License 2.0 发布。部分捆绑的第三方库可能采用各自许可证,以其目录内说明为准。
安装指南
Hope CMS(希望CMS)安装流程:上传程序包 → 配置数据库 → 创建管理员 → 加固安全 → 更新缓存。
环境要求
| 项目 |
要求 |
| PHP |
7.0+(推荐 8.0+;建议同时验证 7.4 / 8.x) |
| 数据库 |
MySQL 5.6+ / MariaDB 10.3+(mysqli 或 pdo_mysql) |
| Web |
Apache / Nginx(IIS 需 URL Rewrite) |
| 扩展 |
建议:mbstring、json、curl、gd 或 imagick、openssl |
目录需可写:content/upload/、content/cache/(Linux 常见权限 755/775,属主为 Web 用户)。
安装步骤
- 从官方下载页获取最新安装包并解压
- 上传到网站根目录,或子目录(子目录须正确配置
SITE_URL / 伪静态 RewriteBase)
- 确认上述目录可写
- 访问
http://你的域名/install.php 进入安装向导
- 填写数据库信息与管理员账号,完成安装
- 立即删除或重命名
install.php
成功安装会写入 content/cache/install.lock,并尝试将 install.php 重命名为 install.php.disabled(仓库备份常为 install.php.bak)
重装
- 删除
content/cache/install.lock
- 设置环境变量
HOPE_ALLOW_REINSTALL=1(若程序要求)
- 必要时从
install.php.bak 恢复 install.php
- 重新访问安装向导
重装会覆盖库表数据,生产环境请先备份数据库与 content/upload/。
安装后必做
- 登录后台(默认入口
admin.php)
- 重命名后台入口:将根目录
admin.php 改为不易猜测的文件名(如 manage_x8k2.php),并更新收藏夹
仍使用 admin.php 时,示例插件「小贴士」会在后台首页提示安全风险
- 外观 → 主题:启用所需主题;有
options.php 时可配置品牌等
- 设置:站点名称、链接模式(动态 / 伪静态)等
- 插件 → 插件管理:按需启用(如支付、OAuth 等)
- 若使用伪静态:配置服务器重写,见 伪静态与路由
- 按需配置 SMTP、支付网关等
- 执行一次 设置 → 更新缓存
常见问题
打开 install.php 空白 / 报错
- 检查 PHP 版本与必装扩展
- 查看
content/cache/ 或 Web 服务器错误日志
- 确认未误删
system/ 或 content/ 关键文件
提示目录不可写
- 调整
content/cache、content/upload 权限与属主
- 部分主机禁止
777,优先用属主可写的 755/775
安装完成仍可访问 install.php
- 手动删除或重命名
install.php
- 确认存在
content/cache/install.lock
子目录安装后样式 / 链接错乱
- 后台核对站点 URL(含路径与尾斜杠)
- 伪静态时修正
RewriteBase 或 Nginx location 前缀
- 更新缓存后再测
后台无法登录
- 确认使用的是重命名后的入口文件
- 清除浏览器 Cookie 后重试
- 数据库
user 表管理员账号是否安装成功
从旧版本升级
已有站点不要再跑安装向导。覆盖文件、插件字段迁移与缓存刷新见 升级与更新。
开发环境与目录约定见 开发准备工作。
升级与更新
本文说明 Hope CMS 插件/主题升级、数据库字段迁移与站点缓存刷新。
适用场景速查
| 场景 |
推荐做法 |
详见 |
| 插件版本迭代加字段 |
callback_up() + 幂等 schema 升级 |
插件更新 |
| 主题启用时建表 |
主题 callback_init() 内执行 |
主题更新 |
| 改菜单/标签/分类名后前台未变 |
后台「设置 → 更新缓存」 |
更新缓存 |
| 仅刷新某一类缓存 |
$CACHE->updateCache('menu') 等 |
更新缓存 |
覆盖更新核心目录时可能改写 system/。业务扩展请写在 content/plugin/、content/theme/,勿直接改核心后指望下次升级保留。
升级前建议:备份数据库 + 备份 content/upload/ +(可选)整站文件快照,便于回滚。
插件更新
插件目录:content/plugin/{插件名}/。
生命周期
| 回调 |
时机 |
建议 |
callback_init() |
启用时 |
建表、初始化 Storage、幂等 schema |
callback_up() |
更新时 |
再跑同一 schema 升级函数 |
callback_rm() |
删除时 |
Storage::deleteAllName('YES');按需 SqlRunner::dropTables |
启用顺序:加载 {插件}_callback.php → callback_init()(不再自动执行 install.sql)。
推荐写法
// tips_callback.php(无表)
function callback_up() {
callback_init();
}
function callback_init() {
// 有表时:myplugin_upgrade_schema();
}
function callback_rm() {
Storage::getInstance('tips')->deleteAllName('YES');
}
有表插件将 CREATE + ALTER 放在同一升级函数,参考 oauth_upgrade_schema()。完整示例见 数据库与 SQL。
字段升级原则
- 建表用
CREATE TABLE IF NOT EXISTS
- 新字段先
SHOW COLUMNS 再 ALTER(可重复执行)
callback_init 与 callback_up 调用同一函数,避免「只更新未重装」漏跑
- 禁止改核心表结构(
article、user、option 等)
主题更新
- 建表 / 初始化:主题根目录
callback.php 的 callback_init()(删除时 callback_rm())
- CSF
options.php 增删字段后,模板读取必须带默认值:hope_option('key', 'default') / _hope()
- 新增
page/*.php 页面模板后:后台新建页面并选择该模板;若主题有「页面入口」类设置,再填写 URL 或页面 ID
$prefix(如 default_options)不要随意改名,否则已保存配置会失效
主题结构与模板变量见 主题开发指南。
更新缓存
后台:设置 → 数据 → 更新缓存(或系统设置中的「更新缓存」入口)。
会做什么
全量 Cache::updateCache(),重建包括但不限于:
options、user、sta、comment、tags、sort、link、menu、newlog、record、logalias、logsort、logtags
并尽量重置路由相关缓存(若存在 Option::resetRoutingTableCache())。
菜单标题同步
刷新 menu 时会先 Menu_Model::syncLinkedMenuTitles():
- 文章 / 页面 / 分类 / 标签 类型菜单项,标题同步为来源最新名称
- 自定义链接菜单名不受影响
改了标签名、分类名或文章标题后,点一次「更新缓存」即可让导航跟上。标签保存/删除时也会自动刷新 tags + menu。
代码中局部刷新
global $CACHE;
$CACHE = Cache::getInstance();
$CACHE->updateCache(); // 全量
$CACHE->updateCache(['tags', 'menu', 'sort']); // 指定
$CACHE->updateArticleCache(); // 文章相关常用组合(含 menu)
缓存文件在 content/cache/*.php;写入后会尝试 opcache_invalidate。请确保目录可写。
开发自检清单
- [ ] 插件
Version 头信息已递增
- [ ] 新表与新字段在幂等升级函数中(
callback_init / callback_up)
- [ ]
callback_rm 已清理 Storage;有表则明确是否 DROP
- [ ] 未改核心表结构与
system/ 业务文件
- [ ] 主题新配置均有默认值;
$prefix 未误改
- [ ] 升级前已备份;升级后已「更新缓存」并抽查前台
相关文档
开发准备工作
Hope CMS(希望CMS)支持主题与插件扩展。本文说明本地环境、目录约定、常用 API 与挂载点,便于二次开发。
开发环境
| 项目 |
要求 |
| PHP |
7.0 及以上(建议同时测试 8.0 / 8.3) |
| MySQL |
5.6+ / MariaDB 10.3+ |
| Web 服务器 |
Apache / Nginx |
| PHP 扩展 |
mysqli 或 pdo_mysql;建议 mbstring、json、curl |
| 浏览器 |
Chrome / Edge 等现代浏览器 |
本地调试时,将站点根目录(含 index.php)配置为 Web 根目录,并确保 content/upload/、content/cache/ 可写。
目录结构
hopecms/ # 站点根目录(HOPE_ROOT)
├── index.php # 前台入口
├── admin.php # 后台入口
├── system/ # 系统核心(升级会覆盖,勿直接改业务)
│ ├── config.php # 数据库、AUTH_KEY 等配置
│ ├── base.php # 引导:插件加载、doAction('init')
│ ├── app/
│ │ ├── controller/ # 前台控制器(Log_Controller、Api_Controller 等)
│ │ ├── model/ # 数据模型
│ │ └── service/ # 业务服务(user_center.php 等)
│ ├── admin/ # 后台业务逻辑(与 content/admin 视图配对)
│ └── lib/
│ ├── common.php # 全局函数、钩子 API、hope_option()
│ ├── hooks.php # HopeHooks 挂载点常量
│ └── database/ # Database、SqlRunner、Storage
└── content/ # ★ 开发者主要工作区
├── plugin/ # 插件目录
├── theme/ # 主题目录
├── admin/ # 后台 HTML 视图(可覆盖 system/admin 输出)
├── upload/ # 用户上传文件
├── cache/ # 运行时缓存 PHP 错误日志
开发者主要工作在 content/plugin/ 与 content/theme/。 新业务类如需放入核心层,应放在 system/app/model、controller、service;目录与请求流程见本文上文。
快速上手:从示例插件起步
官方示例插件:content/plugin/tips/
- 对照或复制
tips 目录,改名后修改 Plugin Name 与钩子函数
- 后台 插件 → 插件管理 中启用
- 启用时核心加载
{插件}_callback.php 并调用 callback_init()
// tips.php
addAction('adm_main_top', 'tips_render_admin_banner');
addAction('adm_head', 'tips_enqueue_admin_css');
// tips_callback.php
function callback_init() { /* 启用即生效 */ }
function callback_rm() {
Storage::getInstance('tips')->deleteAllName('YES');
}
启用后打开后台首页即可看到小贴士横幅。完整说明(生命周期、设置页、前台页、建表、安全清单)见 插件开发指南。
快速上手:从示例主题扩展页面
官方示例主题:content/theme/default/
- 在
content/theme/default/page/ 下新建页面模板,或复制整套主题再改名
- 文件首行写
/*@name 关于我们*/,供后台选择模板时显示中文名
- 后台 页面 → 新建页面,模板选择对应文件
- 布局参考同主题
header.php / footer.php
<?php
/*@name 关于我们*/
defined('HOPE_ROOT') || exit('access denied!');
?>
<section class="about">
<h1><?= htmlspecialchars(hope_option('site_brand', 'Hope CMS')) ?></h1>
</section>
<?php include View::getView('footer'); ?>
主题文件清单、CSF 设置、模板变量、module.php / plugins.php / callback.php 约定见 主题开发指南。
请求流程(简要)
| 入口 |
流程 |
前台 index.php |
base.php → 加载已启用插件 → include 主题 plugins.php(若有)→ doAction('init') → Dispatcher 匹配路由 → Controller → 主题模板 |
后台 admin.php(或重命名后的入口) |
base.php → system/admin/globals.php 按 act 分发 → system/admin/{act}.php → content/admin/{act}.php 渲染 |
| REST API |
?rest-api=方法名 → Api_Controller → Output::ok() / Output::error() |
| 插件设置页 |
{后台入口}?act=plugin_set&plugin=插件名 → {插件}_setting.php 的 plugin_setting_view() |
插件可通过 HopeHooks::ROUTING_REGISTER 挂载点注册前台伪静态路由,详见 伪静态与路由。
常用常量
在已加载 Hope CMS 环境的 PHP 文件中可直接使用:
| 常量 |
说明 |
示例 / 来源 |
HOPE_ROOT |
站点根目录绝对路径 |
F:/linzichen/hopecms/ |
DB_PREFIX |
数据库表前缀 |
hope_(定义于 system/config.php) |
DB_NAME |
数据库名 |
— |
SITE_URL |
站点 URL(含末尾 /) |
http://localhost/cms/ |
THEME_PATH |
当前主题目录 |
.../content/theme/default/ |
THEME_URL |
当前主题 URL |
http://localhost/cms/content/theme/default/ |
PLUGIN_PATH |
插件根目录 |
.../content/plugin/ |
PLUGIN_URL |
插件 URL 前缀 |
http://localhost/cms/content/plugin/ |
ADMIN_TEMPLATE_PATH |
后台视图目录 |
.../content/admin/ |
ISLOGIN |
是否已登录 |
true / false |
UID |
当前用户 ID |
未登录为 0 |
ROLE |
当前用户角色 |
admin / editor / writer / visitor |
路径常量(system/bootstrap/paths.php):HOPE_PATH_APP、HOPE_PATH_MODEL、HOPE_PATH_CONTROLLER、HOPE_PATH_SERVICE、HOPE_PATH_ADMIN、HOPE_PATH_LIBRARY。
用户角色
| 角色常量 |
值 |
典型权限 |
ROLE_ADMIN |
admin |
全部后台权限 |
ROLE_EDITOR |
editor |
管理内容与评论 |
ROLE_WRITER |
writer |
管理自己的文章 |
ROLE_VISITOR |
visitor |
前台只读 |
插件后台页由核心路由保障管理员权限;若插件提供独立 AJAX 接口,需自行校验:
if (!LoginAuth::isLogin() || ROLE !== ROLE_ADMIN) {
Output::authError('权限不足');
}
开发规范
- PHP 编码遵循 PSR-1、PSR-12
- 插件/主题 PHP 文件开头应校验常量:
defined('HOPE_ROOT') || exit('access denied!');
- 主题配置统一用
hope_option('字段名', '默认值') 或 _hope()
- 数据库访问统一用
Database 类,禁止在业务代码中调用 Database::getInstance()->query()
- 输出用户内容到 HTML 时使用
htmlspecialchars() 或 htmlClean()
开启开发者模式
方式一(推荐): 在 system/config.php 末尾添加:
const ENVIRONMENT = 'develop';
方式二: 后台 设置 → 基本 中开启「调试模式」(写入 hope_option 的 debug = y)。
开发模式下 display_errors 开启,错误信息更完整。上线前请删除 ENVIRONMENT 常量或改回 production,并关闭后台调试模式。 错误日志默认写入 content/cache/error.log。
挂载点机制
Hope CMS 通过挂载点(Hook)实现扩展,核心 API 位于 system/lib/common.php,常量定义于 system/lib/hooks.php(HopeHooks 类)。
// 注册(推荐使用 HopeHooks 常量;对照 tips 插件)
addAction(HopeHooks::ADM_HEAD, 'tips_enqueue_admin_css');
addAction(HopeHooks::ADM_MAIN_TOP, 'tips_render_admin_banner');
三种执行方式:
| 函数 |
行为 |
典型场景 |
doAction($hook, ...$args) |
执行该挂载点上所有回调 |
输出 CSS/JS、记录日志 |
doOnceAction($hook, $input, &$ret) |
仅执行第一个回调,可修改 $ret |
接管上传(UPLOAD_MEDIA) |
doMultiAction($hook, $input, &$ret) |
链式执行所有回调,逐级变换 $ret |
正文过滤(ARTICLE_CONTENT_ECHO) |
辅助 API:removeAction($hook, $callback)、hasAction($hook, $callback)。
完整挂载点说明(含参数与示例)见 挂载点手册。 常量源码:system/lib/hooks.php。
常用挂载点速查
| 挂载点常量 |
字符串值 |
位置 / 用途 |
HopeHooks::INIT |
init |
插件与主题 hooks 加载完成后 |
HopeHooks::INDEX_HEAD |
index_head |
前台 <head> |
HopeHooks::INDEX_FOOTER |
index_footer |
前台页脚脚本前 |
HopeHooks::INDEX_BODY_START |
index_body_start |
前台 <body> 开始后 |
HopeHooks::INDEX_BODY_END |
index_body_end |
前台 </body> 前 |
HopeHooks::ADM_HEAD |
adm_head |
后台 <head> |
HopeHooks::ADM_FOOTER |
adm_footer |
后台页脚 |
HopeHooks::ADM_MENU |
adm_menu |
后台侧栏菜单 |
HopeHooks::ADM_MENU_EXT |
adm_menu_ext |
后台侧栏菜单末尾 |
HopeHooks::ADM_WRITELOG_BAR |
adm_writelog_bar |
后台编辑器工具栏 |
HopeHooks::USER_MENU |
user_menu |
用户中心侧栏 |
HopeHooks::USER_CENTER_API |
user_center_api |
个人中心 API 扩展 |
HopeHooks::SAVE_LOG |
save_log |
文章/页面保存后 |
HopeHooks::DEL_LOG |
del_log |
文章/页面删除后 |
HopeHooks::LOG_RELATED |
log_related |
文章页相关推荐区 |
HopeHooks::LOG_VIEW |
log_view |
文章页渲染前 |
HopeHooks::UPLOAD_MEDIA |
upload_media |
媒体上传(doOnceAction 接管) |
HopeHooks::SAVE_SETTING |
save_setting |
系统设置保存后 |
HopeHooks::ROUTING_REGISTER |
routing_register |
扩展前台路由表 |
HopeHooks::PLUGIN_ACTIVE |
plugin_active |
插件启用 |
HopeHooks::PLUGIN_INACTIVE |
plugin_inactive |
插件停用 |
配置与选项
系统级配置
后台「设置」写入 hope_option 表,通过 Option 类读写:
$blogname = Option::get('blogname');
Option::updateOption('apikey', $key);
Option::updateOption('is_openapi', 'y'); // 开启 REST API
主题配置(CSF)
主题 options.php 中定义的字段,保存后通过 hope_option() 读取(带缓存):
$brand = hope_option('site_brand', 'Hope CMS');
$logo = hope_option('site_logo');
插件私有配置
推荐 Storage,数据写入 hope_storage 表,按插件名隔离:
$storage = Storage::getInstance('tips');
$storage->setValue('config', ['foo' => 'bar'], 'array');
$config = $storage->getValue('config');
// 卸载时清理(见 tips_callback.php)
$storage->deleteAllName('YES');
简单开关、计数等无需单独建表;大量结构化数据见 数据库与 SQL。
输入输出
读取请求
$id = Input::getIntVar('id'); // GET 整数
$page = Input::getIntVar('page', 1, 1); // 默认 1,最小 1
$name = Input::postStrVar('name'); // POST 字符串(addslashes)
$password = Input::postRawStr('password'); // POST 原始字符串(密码等)
$ids = Input::postIntArray('ids', []); // POST 整数数组
$keyword = Input::getStrVar('keyword', '');
API 统一输出
Output::ok(['list' => $rows]); // { "code": 200, "msg": "ok", "data": ... }
Output::error('参数错误'); // { "code": 0, "msg": "..." }
Output::authError('未登录'); // 鉴权失败
// 等价于 Response 类
Response::success($data);
Response::fail('错误信息');
Response::authFail('未登录');
错误出口
hope_abort('权限不足', './'); // API 请求自动 JSON;页面请求自动 hpMsg 跳转
模板与 URL
加载主题模板
include View::getView('header'); // THEME_PATH/header.php
include View::getView('page/page_docs'); // 自定义页面
include View::getUserView('index'); // THEME_PATH/user/index.php(个人中心)
生成链接
Url::log($gid); // 文章/页面 URL
Url::sort($sid); // 分类 URL
Url::tag($tagname); // 标签 URL
URL 规则受后台「设置 → 链接」中 rule_article、rule_page 等影响,支持伪静态占位符 {%id%}、{%alias%} 等。完整说明见 伪静态与路由。
参考示例
| 类型 |
路径 |
说明 |
| 示例插件 |
content/plugin/tips/ |
入口、钩子、callback、设置页、assets |
| 示例主题 |
content/theme/default/ |
列表/详情、侧边栏、用户中心、options |
| 有表插件 |
content/plugin/oauth/、video/、music/ |
schema 升级、Storage、伪静态扩展 |
下一步
挂载点手册
Hope CMS 通过挂载点(Hook)扩展功能,核心定义于 system/lib/hooks.php(HopeHooks 常量),注册/触发 API 在 system/lib/common.php。
相关:开发准备工作 · 插件开发指南 · 伪静态与路由
API 一览
// 注册(推荐常量)
addAction(HopeHooks::INDEX_HEAD, 'myplugin_head_css');
addAction('adm_main_top', 'tips_render_admin_banner'); // 字符串亦可
// 触发
doAction(HopeHooks::INDEX_HEAD);
doAction(HopeHooks::SAVE_LOG, $gid, $logData);
| 函数 |
行为 |
典型场景 |
doAction($hook, ...$args) |
执行该点全部回调 |
输出 CSS/JS、记日志 |
doOnceAction($hook, $input, &$ret) |
仅第一个回调,可改 $ret |
接管上传、用户中心 API |
doMultiAction($hook, $input, &$ret) |
链式执行,逐级变换 $ret |
正文过滤 |
removeAction($hook, $callback) |
移除回调 |
调试 / 互斥 |
hasAction($hook, $callback) |
是否已注册 |
条件注册 |
约定:
- 回调内输出用户内容用
htmlspecialchars
- 需要 JSON 中断时用
Output::* / hope_abort(),避免半截 HTML
- 函数名加插件前缀,避免冲突
启动与路由
| 常量 |
字符串 |
说明 |
HopeHooks::INIT |
init |
插件与主题 plugins.php 加载完成后(base.php 末尾) |
HopeHooks::ROUTE_DISPATCH |
route_dispatch |
路由分发前(model, method, params) |
HopeHooks::ROUTING_REGISTER |
routing_register |
路由表构建后扩展(doMultiAction,可追加规则) |
HopeHooks::PAGE_NOT_FOUND |
page_not_found |
404 页 |
addAction(HopeHooks::ROUTING_REGISTER, 'myplugin_register_routes');
详见 伪静态与路由。
前台页面
| 常量 |
字符串 |
建议埋点位置 |
INDEX_HEAD |
index_head |
</head> 前 |
INDEX_BODY_START |
index_body_start |
<body> 后 |
INDEX_SIDEBAR |
index_sidebar |
侧边栏 widgets 之前 |
INDEX_FOOTER |
index_footer |
页脚脚本前 |
INDEX_BODY_END |
index_body_end |
</body> 前 |
主题模板负责 doAction(...),插件负责 addAction(...)。
文章与评论
| 常量 |
字符串 |
参数 / 说明 |
LOG_VIEW |
log_view |
文章页渲染前(logid, logData) |
ARTICLE_CONTENT_ECHO |
article_content_echo |
正文输出前过滤(doMultiAction) |
LOG_RELATED |
log_related |
相关推荐 / 扩展区 |
LOG_DIRECT_LINK |
log_direct_link |
外链跳转前 |
SAVE_LOG |
save_log |
文章/页面保存后 |
DEL_LOG |
del_log |
文章/页面删除后 |
COMMENT_FORM |
comment_form |
评论表单区 |
COMMENT_POST |
comment_post |
评论提交前 |
COMMENT_SAVED |
comment_saved |
评论保存后 |
COMMENT_REPLY |
comment_reply |
后台回复评论后 |
POST_COMMENT |
post_comment |
前台评论发布成功 |
POST_NOTE |
post_note |
微语/笔记发布 |
addAction(HopeHooks::ARTICLE_CONTENT_ECHO, function ($content, &$ret) {
$ret = str_replace('foo', 'bar', $ret ?: $content);
});
用户与登录
| 常量 |
字符串 |
说明 |
USER_MENU |
user_menu |
用户中心侧栏扩展 |
USER_CENTER_API |
user_center_api |
个人中心 API(doOnceAction,可接管 action) |
LOGIN_HEAD |
login_head |
登录页 head |
LOGIN_EXT |
login_ext |
登录表单扩展 |
LOGIN_SUCCESS |
login_success |
登录成功 |
SIGNUP_EXT |
signup_ext |
注册表单扩展 |
addAction(HopeHooks::USER_MENU, function () {
echo '<a href="' . htmlspecialchars(Url::plugin('myplugin')) . '">我的扩展</a>';
});
后台
| 常量 |
字符串 |
说明 |
ADM_HEAD |
adm_head |
后台 <head> |
ADM_FOOTER |
adm_footer |
后台页脚 |
ADM_MAIN_TOP |
adm_main_top |
后台首页顶部(如 tips 横幅) |
ADM_MAIN_BOTTOM |
adm_main_bottom |
后台首页底部 |
ADM_MENU |
adm_menu |
侧栏菜单项(靠前位置) |
ADM_MENU_EXT |
adm_menu_ext |
侧栏菜单末尾 |
ADM_WRITELOG_BAR |
adm_writelog_bar |
写文章工具栏 |
ADM_COMMENT_DISPLAY |
adm_comment_display |
评论列表扩展 |
ADM_LINK_DISPLAY |
adm_link_display |
链接列表扩展 |
ADM_USER_DISPLAY |
adm_user_display |
用户列表行($user) |
ADM_USER_FORM |
adm_user_form |
用户编辑表单 |
addAction(HopeHooks::ADM_MENU_EXT, function () {
echo '<li><a href="./plugin.php?plugin=myplugin">我的插件</a></li>';
});
具体菜单 HTML 结构请对照当前后台模板,避免破坏布局。
用户管理事件
| 常量 |
字符串 |
参数 |
ADD_USER |
add_user |
uid, userData |
UPDATE_USER |
update_user |
uid, userData |
DEL_USER |
del_user |
uid |
FORBID_USER |
forbid_user |
uid |
UNFORBID_USER |
unforbid_user |
uid |
媒体与下载
| 常量 |
字符串 |
说明 |
UPLOAD_MEDIA |
upload_media |
附件上传(常配合 doOnceAction 接管) |
DEL_MEDIA |
del_media |
附件删除 |
ATTACH_UPLOAD |
attach_upload |
编辑器附件上传 |
DOWNLOAD_RESOURCE |
download_resource |
资源下载 |
分类、设置与插件生命周期
| 常量 |
字符串 |
说明 |
SAVE_SORT / DEL_SORT |
save_sort / del_sort |
分类保存 / 删除后 |
SAVE_SETTING |
save_setting |
系统设置保存后 |
PLUGIN_ACTIVE |
plugin_active |
插件启用 |
PLUGIN_INACTIVE |
plugin_inactive |
插件停用 |
PLUGIN_DELETED |
plugin_deleted |
插件删除 |
LANG_LOADED |
lang_loaded |
语言包加载后 |
GET_GRAVATAR |
get_Gravatar |
Gravatar 地址(doOnceAction) |
示例:最小可用
// myplugin.php
addAction(HopeHooks::ADM_HEAD, 'myplugin_admin_css');
addAction(HopeHooks::SAVE_LOG, 'myplugin_on_save');
function myplugin_admin_css() {
echo '<link rel="stylesheet" href="' . PLUGIN_URL . 'myplugin/assets/admin.css">' . "\n";
}
function myplugin_on_save($gid, $data = null) {
// 文章保存后的业务逻辑
}
源码常量以 system/lib/hooks.php 为准;本页与代码不一致时以代码为准。
数据库与 SQL
Hope CMS 使用 MySQL / MariaDB 存储数据。数据库操作统一通过 Database 类与 SqlRunner 执行器完成。
- 生命周期 / Storage:对照示例插件
tips
- 自建表:
tips 无表;有表时对照 oauth、video、music 的 *_upgrade_schema() / callback_init(),卸载时 dropTables
核心类与文件
| 类 / 文件 |
路径 |
说明 |
Database |
system/lib/database/database.php |
数据库入口,提供链式查询与快捷方法 |
DatabaseQueryBuilder |
system/lib/database/databasequerybuilder.php |
链式查询构建器 |
SqlRunner |
system/lib/database/sqlrunner.php |
SQL 文件读取与批量执行 |
Storage |
system/lib/database/storage.php |
插件键值存储(写入 hope_storage 表) |
表前缀
系统安装时在 system/config.php 中定义表前缀常量:
const DB_PREFIX = 'hope_';
约定:
- 使用
Database::table('article') 时,不要手动加前缀,框架会自动拼接为 hope_article
- 编写原生 SQL 时,可拼接
DB_PREFIX,或在 SqlRunner::executeLines / executeFile 中使用占位符 {db_prefix}
- 少数场景需手动拼接:
DB_PREFIX . 'myplugin_log'
链式查询(推荐)
// 查询列表
$rows = Database::table('myplugin_log')
->where(['status' => 1, 'uid' => $uid])
->whereLike('title', $keyword)
->whereIn('id', $ids)
->order('id DESC')
->limit(20, 0)
->findAll();
// 查询单条
$row = Database::table('myplugin_log')->where(['id' => $id])->find();
// 统计
$total = Database::table('myplugin_log')->where(['status' => 1])->count();
// JOIN 查询(带表别名)
$list = Database::table('myplugin_log', 'l')
->select(['l.id', 'l.title', 'u.nickname'])
->leftJoin('user', 'u', 'l.uid = u.uid')
->where(['l.status' => 1])
->order('l.id DESC')
->limit(10)
->findAll();
链式方法一览
| 方法 |
说明 |
select($fields) |
指定字段,支持数组或字符串 |
where($condition) |
条件,支持数组 ['id'=>1] 或字符串 "id=1 AND status=1" |
whereRaw($sql) |
原生 WHERE 片段 |
whereIn($field, $values) |
IN 查询,空数组自动变为 1=0 |
whereLike($field, $value) |
模糊搜索,自动转义 %、_ |
join / leftJoin |
表关联 |
order($order) |
排序,如 'id DESC' |
limit($limit, $offset) |
分页 |
group($group) |
GROUP BY |
findAll() |
返回多行数组 |
find() |
返回单行或 null |
insert($data) |
插入,返回自增 ID |
update($data) |
更新(需先 where) |
delete() |
删除(需先 where) |
count() |
计数 |
快捷方法
适合简单 CRUD,无需链式调用:
Database::select('article', ['hide' => 'n']);
Database::getOne('user', ['uid' => 1]);
Database::insert('myplugin_log', ['title' => '示例', 'status' => 1]);
Database::update('myplugin_log', ['id' => 1], ['status' => 0]);
Database::delete('myplugin_log', ['id' => 1]);
Database::count('myplugin_log', ['status' => 1]);
原生 SQL
复杂统计、聚合或 ON DUPLICATE KEY 等场景可使用原生 SQL:
// 读:多行
$rows = Database::fetchAll(
'SELECT * FROM `' . DB_PREFIX . 'myplugin_log` WHERE uid = ' . (int)$uid
);
// 读:单行
$row = Database::fetchOne('SELECT COUNT(*) AS cnt FROM `' . DB_PREFIX . 'myplugin_log`');
// 写
Database::execute('UPDATE `' . DB_PREFIX . 'myplugin_log` SET views = views + 1 WHERE id = ' . (int)$id);
// 字符串转义(仅用于少量 whereRaw / 原生 SQL)
$safe = Database::escape($keyword);
优先使用链式 where / whereLike;原生 SQL 中数值请 (int) 强转,字符串务必 Database::escape()。
插件/主题建表(callback_init)
不再使用目录下的 install.sql 自动执行。启用时核心只调用 callback_init()。
无表插件对照 tips:
// content/plugin/tips/tips_callback.php
function callback_init() { /* 启用即生效 */ }
function callback_rm() {
Storage::getInstance('tips')->deleteAllName('YES');
}
有表时在升级函数中建表(对照 oauth_upgrade_schema()):
function oauth_upgrade_schema() {
$table = DB_PREFIX . 'oauth_bind';
if (Database::fetchOne("SHOW TABLES LIKE '{$table}'")) {
return;
}
Database::execute("CREATE TABLE IF NOT EXISTS `{$table}` ( ... )", true);
}
function callback_init() {
require_once HOPE_ROOT . 'content/plugin/oauth/oauth_lib.php';
oauth_upgrade_schema();
}
function callback_rm() {
Storage::getInstance('oauth')->deleteAllName('YES');
SqlRunner::dropTables(['oauth_bind']);
}
何时执行
| 时机 |
调用链 |
| 插件启用 |
Plugin_Model::activePlugin() → callback_init() |
| 主题启用 |
Theme_Model::initCallback() → callback_init() |
| 插件升级 |
callback_up()(通常再调同一 upgrade 函数) |
| 手动 SQL 文件 |
Database::executeFile($path, $options) / SqlRunner::executeFile()(备份恢复等) |
SqlRunner 高级选项
SqlRunner::executeFile(HOPE_ROOT . 'path/to/custom.sql', [
'replace_prefix' => true, // 替换 {db_prefix}
'ignore_error' => false, // 遇错是否继续
'charset_setup' => false, // 是否调整库字符集
'version_gate' => false, // 是否解析 # pro x.x 版本门禁行
]);
SqlRunner::dropTables(['table_a', 'table_b']) 用于卸载时按逻辑表名(不含前缀)批量 DROP。
version_gate 示例(升级包 SQL 中可用):
# 2.0.0
ALTER TABLE `{db_prefix}option` ADD COLUMN ...
当当前版本高于指定版本时,后续 SQL 不再执行。
字段升级(Schema Migration)
建表用 CREATE TABLE IF NOT EXISTS;给已有表加字段应在升级函数中检测后 ALTER:
function oauth_upgrade_schema_fields() {
static $done = false;
if ($done) return;
$done = true;
$table = DB_PREFIX . 'oauth_bind';
Database::execute("CREATE TABLE IF NOT EXISTS `{$table}` (...)", true);
$existing = [];
foreach (Database::fetchAll("SHOW COLUMNS FROM `{$table}`") as $col) {
$existing[$col['Field']] = true;
}
if (empty($existing['new_field'])) {
Database::execute(
"ALTER TABLE `{$table}` ADD COLUMN `new_field` varchar(100) NOT NULL DEFAULT ''",
true
);
}
}
在 callback_init() / callback_up() 中调用同一函数即可。
Storage 插件存储
插件配置、缓存类数据可存入 hope_storage,无需自建表:
$storage = Storage::getInstance('tips');
$storage->setValue('config', [
'enabled' => 'y',
'per_page' => 20,
], 'array');
$config = $storage->getValue('config');
// 删除插件全部数据(callback_rm 中常用,见 tips)
$storage->deleteAllName('YES');
系统核心表(只读参考)
开发插件时不得修改以下核心表结构,仅可通过 Model / API 读写:
| 逻辑名 |
实际表名 |
说明 |
article |
hope_article |
文章/页面 |
user |
hope_user |
用户 |
comment |
hope_comment |
评论 |
sort |
hope_sort |
分类 |
tag |
hope_tag |
标签 |
media |
hope_media |
附件资源 |
option |
hope_option |
系统配置 |
storage |
hope_storage |
插件键值存储 |
pay_order |
hope_pay_order |
支付订单 |
插件自建表命名建议:{DB_PREFIX}{插件名}_{用途},如 hope_oauth_bind。
开发建议
- 生命周期 → 先对照
tips 写好 callback_* 与 Storage
- 新建表 → 写在
callback_init / *_upgrade_schema()(可参考 oauth)
- 加字段 → 同一升级函数内
SHOW COLUMNS + ALTER TABLE
- 日常查询 → 优先
Database::table() 链式
- 复杂 SQL →
fetchAll / fetchOne / execute,注意转义
- 卸载清理 →
callback_rm() 必须清 Storage;有表则 dropTables,不留痕
插件开发指南
插件是在不修改 system/ 核心的前提下扩展 Hope CMS 的主要方式:通过挂载点(Hook)插入逻辑、可选建表、提供后台设置页与前台页面。
官方示例插件:[content/plugin/tips/](../../plugin/tips/)(小贴士)。无自建表、结构完整,适合作为脚手架。
有表 / 存储的对照:content/plugin/oauth/(callback_init 建表 + Storage 配置)。
相关文档:开发准备工作 · 挂载点手册 · 数据库与 SQL · 升级与更新 · 伪静态与路由 · API 开发文档
1. 从 tips 起步
- 复制
content/plugin/tips/ → content/plugin/你的插件名/
- 目录名与入口文件名一致:
你的插件名/你的插件名.php
- 重命名
tips_*.php,并全局替换函数前缀(如 tips_ → myplugin_)
- 修改入口文件头信息中的 Plugin Name / Description / Version
- 后台 插件 → 插件管理 启用
- 确认钩子生效;需要持久化时再补 Storage / 建表
启用时核心流程:写入 active_plugins → 加载 {插件}_callback.php → 调用 callback_init()(不会自动执行 install.sql)。
每请求加载:对已启用插件 include_once content/plugin/{名}/{名}.php,再加载当前主题 plugins.php,最后 doAction('init')。
2. 目录结构
content/plugin/tips/
├── tips.php # 必需:入口 + 头信息 + 注册钩子
├── tips_callback.php # 强烈推荐:启用 / 更新 / 删除
├── tips_setting.php # 可选:后台设置页(有则显示「设置」)
├── tips_lib.php # 推荐:业务函数
├── tips_show.php # 可选:前台独立页(Url::plugin)
├── preview.png # 可选:插件列表预览图
└── assets/
└── tips.css
| 文件 |
必需 |
说明 |
{名}.php |
是 |
入口;启用期间每个请求都会加载 |
{名}_callback.php |
强烈建议 |
callback_init / callback_up / callback_rm |
{名}_setting.php |
否 |
定义 plugin_setting_view() |
{名}_lib.php |
建议 |
函数库,由入口 / 设置页 require |
{名}_show.php |
否 |
前台展示页 |
{名}_rewrite.php 等 |
否 |
按需拆分(如 oauth 的伪静态规则) |
命名规则:目录名、入口文件名、钩子函数前缀保持一致,避免冲突。
3. 入口文件与头信息
<?php
/*
Plugin Name: 小贴士
Version: 1.0.0
Plugin URL: http://www.hopecms.cn
Description: 插件启用后,在后台首页随机展示一句内置使用提示。
Author: Hope CMS
Author URL: http://www.hopecms.cn
*/
!defined('HOPE_ROOT') && exit('error');
require_once HOPE_ROOT . 'content/plugin/tips/tips_lib.php';
addAction('adm_main_top', 'tips_render_admin_banner');
addAction('adm_head', 'tips_enqueue_admin_css');
| 头字段 |
说明 |
| Plugin Name |
后台显示名(必需) |
| Version |
版本号 |
| Description |
简介 |
| Plugin URL / Author / Author URL |
可选元数据 |
active_plugins 中存储的是相对路径:tips/tips.php。
4. 生命周期回调
文件:content/plugin/{名}/{名}_callback.php
| 函数 |
时机 |
典型工作 |
callback_init() |
启用时 |
建表、写默认 Storage、注册一次性数据 |
callback_up() |
更新插件后 |
通常再调 callback_init() 或 *_upgrade_schema() |
callback_rm() |
删除前 |
删 Storage、SqlRunner::dropTables([...]) |
tips(无表)
<?php
defined('HOPE_ROOT') || exit('access denied!');
function callback_init() {
}
function callback_up() {
callback_init();
}
function callback_rm() {
Storage::getInstance('tips')->deleteAllName('YES');
}
有表时(对照 oauth)
function callback_init() {
require_once HOPE_ROOT . 'content/plugin/oauth/oauth_lib.php';
oauth_upgrade_schema(); // 内含 CREATE TABLE IF NOT EXISTS
$storage = Storage::getInstance('oauth');
if (!$storage->getValue('config')) {
$storage->setValue('config', oauth_default_config(), 'array');
}
}
function callback_rm() {
Storage::getInstance('oauth')->deleteAllName('YES');
SqlRunner::dropTables(['oauth_bind']); // 不带表前缀
}
要点:
- 建表在 PHP 里执行,不要依赖自动跑
install.sql
Database::table('xxx') 不带前缀;原生 SQL / dropTables 注意 DB_PREFIX
- 卸载是否删表由你决定:商业数据可选择只清 Storage、保留业务表
详见 数据库与 SQL、升级与更新。
5. 挂载点(Hook)
addAction('adm_main_top', 'tips_render_admin_banner');
addAction(HopeHooks::ADM_HEAD, 'tips_enqueue_admin_css'); // 推荐常量
| API |
行为 |
doAction($hook, ...) |
执行该点全部回调 |
doOnceAction($hook, $input, &$ret) |
只跑第一个,可改 $ret |
doMultiAction($hook, $input, &$ret) |
链式变换 $ret |
removeAction / hasAction |
移除 / 判断 |
常用挂载点
| 常量 / 字符串 |
用途 |
init |
插件与主题 hooks 加载完后 |
index_head / index_footer |
前台头尾 |
index_body_start / index_body_end |
body 始末 |
adm_head / adm_footer |
后台头尾 |
adm_menu / adm_menu_ext |
后台侧栏菜单 |
adm_main_top |
后台首页顶部(tips 横幅) |
adm_writelog_bar |
写文章工具栏 |
user_menu |
用户中心侧栏 |
user_center_api |
用户中心 API 扩展 |
save_log / del_log |
文章保存 / 删除后 |
log_view / log_related |
文章渲染前 / 相关推荐 |
comment_saved / post_comment |
评论相关 |
upload_media |
媒体上传(常配合 doOnceAction) |
plugin_active / plugin_inactive |
启停插件时 |
routing_register 等 |
注册前台路由(见伪静态文档) |
完整参数与示例见 挂载点手册 及 开发准备工作 速查表。
约定: 钩子回调里输出 HTML 时对用户数据做 htmlspecialchars;需要中断请求时用 Output::* / hope_abort(),勿随意 die 半截页面。
6. 后台设置页
存在 {名}_setting.php 且插件已启用时,插件列表显示「设置」。
访问:{后台入口}?act=plugin_set&plugin=tips
(默认入口为 admin.php,生产环境应重命名。)
必须定义:
<?php
defined('HOPE_ROOT') || exit('access denied!');
function plugin_setting_view() {
// 输出后台 HTML(可沿用 content/admin 的 Bootstrap / card 样式)
}
保存配置推荐两种方式:
A. Storage(键值,适合开关与小配置)
$storage = Storage::getInstance('myplugin');
$storage->setValue('config', ['enable' => 1], 'array');
$config = $storage->getValue('config');
B. 自建表
用 Database::table(...)->insert/update;设置页里处理 POST 时用 Input::postStrVar 等过滤。
设置页由核心保证管理员登录;若另写 AJAX 接口,须自行校验:
if (!LoginAuth::isLogin() || ROLE !== ROLE_ADMIN) {
Output::authError('权限不足');
}
7. 前台页面 {名}_show.php
放置该文件且插件已启用时,可通过插件路由访问:
$url = Url::plugin('tips'); // 生成链接
$url = Url::plugin('tips', ['id' => 1]);
- 未启用或文件不存在 → 404
- 页面可自绘完整 HTML(如 tips),也可 include 当前主题 header/footer 保持站点风格
include View::getView('header');
// ... 插件内容 ...
include View::getView('footer');
静态资源:
function tips_asset_url($path) {
return PLUGIN_URL . 'tips/assets/' . ltrim($path, '/');
}
| 常量 |
说明 |
PLUGIN_PATH |
content/plugin/ 物理路径 |
PLUGIN_URL |
content/plugin/ URL 前缀 |
8. 数据库与配置
| 场景 |
推荐 |
| 开关、JSON 配置、计数 |
Storage::getInstance('插件名') |
| 列表、关联、订单等 |
自建表 + Database::table |
| 系统级选项 |
Option::get / Option::updateOption(慎用,避免污染核心键) |
$rows = Database::table('myplugin_log')
->where(['uid' => $uid])
->order('id DESC')
->limit(20)
->findAll();
禁止在业务里直接 Database::getInstance()->query() 拼接不可信输入。详见 数据库与 SQL。
9. 安全规范
- 每个 PHP 文件检查
HOPE_ROOT(或等价 !defined('HOPE_ROOT') && exit)
- 读写请求用
Input::getIntVar / postStrVar / postRawStr(密码等)
- 输出 HTML 用
htmlspecialchars;JSON 用 Output::ok / Output::error
- CSRF:后台表单遵循现有 admin 习惯;前台写操作校验登录态与 token(若主题/系统已提供)
- 不修改核心表结构语义;不覆盖
system/、content/admin 核心文件
- SQL 表名、字段名白名单化,勿把用户输入拼进标识符
10. 调试
system/config.php 增加 const ENVIRONMENT = 'develop';,或后台开启调试模式
- 错误日志:
content/logs/ 或 content/cache/error.log
- 改钩子后:禁用再启用插件,确保
callback_init 重跑
- 确认
active_plugins 中路径为 目录/入口.php
- 前台
_show.php 404:检查是否启用、文件名是否 {名}_show.php、链接是否 Url::plugin
11. 与主题的分工
| 能力 |
放插件 |
放主题 |
| 跨主题可复用功能 |
✓ |
|
| 仅当前皮肤的样式 / 布局 |
|
✓ |
| 商业支付、OAuth、统计 |
✓ |
主题只负责展示 |
| CSF 外观选项 |
|
✓ options.php |
| 文章保存后业务逻辑 |
✓ save_log |
主题 hooks 仅皮肤相关 |
Shop 等主题依赖的商业能力应做成普通插件(如 hp_core),可启用 / 禁用 / 删除,而不是改核心。
12. 发布检查清单
- [ ] 头信息完整,Version 可递增
- [ ]
callback_rm 清理 Storage;有表则明确是否 dropTables
- [ ]
callback_up / *_upgrade_schema 可重复执行(IF NOT EXISTS / 判列)
- [ ] 设置页、前台页在未启用时不可访问
- [ ] 函数名、Storage 名、表名带插件前缀,无全局污染
- [ ] 附简短说明(README 或设置页文案)
- [ ] 在 PHP 7.4+ / 8.x 各测一次启停与卸载
13. 最小插件骨架
<?php
/*
Plugin Name: 演示插件
Version: 1.0.0
Description: 最小可运行示例
Author: You
*/
!defined('HOPE_ROOT') && exit('error');
addAction('adm_head', function () {
echo "<!-- myplugin loaded -->\n";
});
仅入口也可运行;正式发布请补全 _callback.php 与卸载清理。
主题开发指南
主题位于 content/theme/{主题目录}/。启用后前台页面由该目录下的 PHP 模板渲染。
官方示例主题:content/theme/default/。学习列表页、侧边栏、用户中心、CSF 设置时优先对照此主题。
相关文档:开发准备工作 · 挂载点手册 · 侧边栏开发说明 · 伪静态与路由 · 数据库与 SQL
1. 从零创建主题
- 复制
content/theme/default/ 为 content/theme/你的主题/
- 修改
header.php 顶部 Theme Name / Version / Description
- 修改
options.php 的 $prefix(如 yourtheme_options)与标题文案
- 将
module.php 中函数前缀(如 nova_*)改为自己的命名空间,避免与其它主题冲突
- 后台 外观 → 主题 启用;如有
callback.php,启用时会执行 callback_init()
- 建议执行一次 设置 → 更新缓存
不要直接改正在线上使用的主题;复制一份再改,便于回滚。
2. 目录结构
content/theme/default/
├── header.php # 必需:主题元信息 + HTML 头部
├── footer.php # 必需:页脚与闭合标签
├── log_list.php # 必需:首页 / 分类 / 标签 / 搜索 / 归档列表
├── echo_log.php # 必需:文章详情
├── 404.php # 推荐:404 页
├── module.php # 推荐:主题函数库(模板中 require)
├── options.php # 可选:CSF 主题设置
├── plugins.php # 可选:主题级钩子(每请求自动 include)
├── callback.php # 可选:启用 / 删除 / 升级回调
├── preview.png # 推荐:后台主题列表预览图
├── widgets/ # 可选:侧边栏(无侧栏可不建)
│ ├── sidebar.php
│ ├── side_config.php
│ └── side_*.php
├── page/ # 可选:独立页面模板
│ └── page.php
├── user/ # 可选:登录 / 注册 / 用户中心(缺则回退 default)
│ ├── index.php
│ ├── login.php
│ ├── register.php
│ ├── user_auth_lib.php
│ └── user_center_lib.php
├── partials/ # 可选:可复用片段
├── css/
└── js/
3. 主题元信息
写在 header.php 文件最顶部的注释块,后台主题列表会解析:
<?php
/*
Theme Name: 默认主题
Theme Type: cms
Theme Url: http://www.hopecms.cn
Author: Hope CMS
Author Url: http://www.hopecms.cn
Version: 1.0.0
Description: Hope CMS 默认主题:大标题首页、双栏列表、标签云侧栏与个人中心。
*/
defined('HOPE_ROOT') || exit('access denied!');
require_once View::getView('module');
| 字段 |
说明 |
| Theme Name |
后台显示名称(必需) |
| Version |
版本号 |
| Description |
简介 |
| Theme Type |
可选分类标签,如 cms |
| Author / Theme Url |
作者与主题主页 |
4. 核心模板与变量
控制器先 include View::getView('header'),再 include 列表或详情模板,最后模板内再 include footer。
4.1 列表页 log_list.php
用于首页、分类、标签、搜索、日期归档、作者页等。常用变量:
| 变量 |
说明 |
$logs |
当前页文章数组 |
$lognum |
符合条件的文章总数 |
$page / $index_lognum / $pageurl |
分页参数 |
$sortName / $sort |
分类名 / 分类信息(分类页) |
$tag |
标签名(标签页) |
$keyword |
搜索关键词(搜索页) |
$record |
归档年月(归档页) |
$author_name |
作者展示名(作者页) |
$page_html = pagination($lognum, $index_lognum, $page, $pageurl);
foreach ($logs as $value) {
// $value['gid'] $value['log_title'] $value['log_cover'] ...
echo '<a href="' . Url::log($value['gid']) . '">' . htmlspecialchars($value['log_title']) . '</a>';
}
4.2 详情页 echo_log.php
| 变量 |
说明 |
$logid / $gid |
文章 ID |
$log_title / $log_content |
标题 / 正文 HTML |
$log_cover |
封面图 URL |
$date / $views / $comnum |
时间戳 / 阅读 / 评论数 |
$author / $sortid / $tags |
作者 UID / 分类 ID / 标签 ID 串 |
$neighborLog |
上一篇 / 下一篇 |
$password |
访问密码(有则需校验) |
列表与详情中均可:
<?php include View::getView('sidebar'); ?>
<?php include View::getView('footer'); ?>
| 变量 |
说明 |
$site_title |
当前页 <title> |
$site_key / $site_description |
SEO keywords / description |
$sitename |
站点名(系统设置) |
头部应输出挂载点,供插件插入 CSS/统计代码:
<?php doAction('index_head'); ?>
页脚:
<?php doAction('index_footer'); ?>
5. 自定义页面
后台创建「页面」时可选择模板,文件放在 page/:
<?php
/*@name 关于我们*/
defined('HOPE_ROOT') || exit('access denied!');
?>
<main>
<h1>关于我们</h1>
<div><?= $log_content ?></div>
</main>
<?php include View::getView('footer'); ?>
@name 后的文字会出现在后台模板下拉里
- 页面同样会先加载
header.php,模板内记得闭合 footer
- 复杂站点(如本主题
hopecms)可有多个:page_docs.php、page_download.php、page_generator.php 等
- 前台「模板生成器」页可按数据源与条件本地生成文章循环、分类/标签、评论、挂载点等 PHP 片段(交互类似 Sndow 模板工具,输出适配 Hope CMS API)
6. module.php
建议所有主题辅助函数集中在此,并在 header.php 中 require_once View::getView('module')。
function your_asset($path) {
return THEME_URL . ltrim($path, '/');
}
function your_brand() {
$name = trim((string) hope_option('site_brand', ''));
return $name !== '' ? $name : (string) Option::get('sitename');
}
| 常量 |
说明 |
THEME_PATH |
当前主题物理路径 |
THEME_URL |
当前主题 URL(末尾一般无 /,拼接时自行处理) |
SITE_URL |
站点根 URL(含末尾 /) |
<link rel="stylesheet" href="<?= your_asset('css/style.css') ?>">
<a href="<?= SITE_URL ?>">首页</a>
生成内容链接用核心类,不要手拼规则:
Url::log($gid); // 文章
Url::sort($sid); // 分类
Url::tag($tagname); // 标签
7. options.php(主题设置)
主题目录内有 options.php 时,后台出现主题设置页(Codestar / CSF)。
约定
| 项 |
说明 |
$prefix |
唯一,推荐 {主题目录}_options;设定后勿改,否则已存配置失效 |
| 读取 |
hope_option('字段id', '默认值') 或 _hope() |
| 无文件 |
无主题设置页,主题仍可正常启用 |
<?php
if (!defined('HOPE_ROOT')) exit;
$prefix = 'yourtheme_options';
CSF::createOptions($prefix, [
'plugin_title' => '某某主题设置',
'footer_text' => 'Hope CMS',
'theme' => 'light', // light | dark | auto
]);
CSF::createSection($prefix, [
'title' => '基本设置',
'icon' => 'fa fa-cog',
'fields' => [
[
'id' => 'site_brand',
'type' => 'text',
'title' => '站点品牌名',
'default' => 'Hope CMS',
],
[
'id' => 'primary_color',
'type' => 'color',
'title' => '主题色',
'default' => '#3b82f6',
],
[
'id' => 'hero_enable',
'type' => 'switcher',
'title' => '启用首页 Hero',
'default' => true,
],
],
]);
options完整的.php 覆盖:文本、选择、开关、上传、颜色、调色板、repeater/group、accordion/tabbed、code_editor、依赖 dependency、backup 等。按需拷贝字段到自己的 options.php。
WordPress Codestar 配置可迁移:API 使用 CSF::;读取用 hope_option(),不要用 get_option。
8. plugins.php(主题钩子)
每个前台请求在加载已启用插件之后,会自动 include 当前主题的 plugins.php(若存在),再执行 doAction('init')。
适合:注册主题专属钩子、挂文章自定义字段、改写用户中心菜单等。
<?php
defined('HOPE_ROOT') || exit('access denied!');
addAction('index_head', 'yourtheme_extra_css');
addAction('user_menu', 'yourtheme_user_menu_item');
default 的 plugins.php 为空壳,可按需扩展。
9. callback.php(主题生命周期)
| 函数 |
时机 |
callback_init() |
主题启用时 |
callback_rm() |
主题删除前 |
callback_up() |
主题升级后(若实现) |
可在启用时建表、写默认配置;删除时清理 Storage / 自建表。建表写法见 数据库与 SQL。
<?php
defined('HOPE_ROOT') || exit('access denied!');
function callback_init() {
// 例如:同步默认配置、建扩展表
}
function callback_rm() {
// 例如:Storage::getInstance('yourtheme')->deleteAllName('YES');
}
10. 侧边栏与用户中心
- 侧边栏:
widgets/ + side_config.php,详见 侧边栏开发说明
- 用户中心:优先使用主题
user/;若主题未提供,系统可能回退到 default/user/
- 登录 / 注册页同理,建议主题内自备完整
user/ 目录,避免混用样式
用户中心模板中可用:
include View::getUserView('index');
11. 挂载点(主题侧)
主题模板负责 埋点,插件负责 注册回调。default 的 header/footer 已含常用前台钩子。
| 挂载点 |
建议位置 |
index_head |
</head> 前 |
index_body_start |
<body> 后 |
index_footer / index_body_end |
页脚脚本区 |
index_sidebar |
侧边栏容器内 |
log_related |
文章相关推荐区 |
完整列表见 挂载点手册。
12. 检查清单与注意事项
- 不硬编码域名,用
SITE_URL、THEME_URL、Url::*
- 输出用户内容用
htmlspecialchars
- 勿修改
system/;业务扩展用主题 plugins.php 或独立插件
$prefix 与函数名前缀全局唯一
hope_option / _hope 始终带默认值
SITE_URL 已有尾斜杠,拼接路径时避免写成 SITE_URL . '/xxx' 变成双斜杠(可用 rtrim(SITE_URL,'/').'/xxx')
- 启用新主题后更新缓存;换主题后检查侧边栏组件是否仍注册
伪静态与 URL 路由
Hope CMS 通过 链接模式(linkmode) 与 路由表 控制前台 URL 形态。后台在 设置 → 链接 中配置;核心路由定义于 system/lib/core/option.php 的 getEnhancedRoutingTable(),由 Dispatcher 匹配并分发到对应 Controller。
链接模式
linkmode |
名称 |
URL 形态 |
说明 |
0 |
动态 |
?article=1、?category=2&page=3 |
无需 Web 服务器重写,兼容性最好 |
1 |
伪静态 |
/article/1.html、/user |
需服务器将路径重写到 index.php |
2 |
index.php 式 |
/index.php/article/1.html |
依赖 PATH_INFO,部分主机更稳定 |
判断伪静态是否生效:
$linkmode = (string) Option::get('linkmode');
$isRewrite = ($linkmode === '1' || $linkmode === '2');
保存链接设置后,系统会调用 Option::resetRoutingTableCache() 刷新路由缓存。
后台 URL 规则
在 设置 → 链接 → 伪静态管理 中可配置以下规则(hope_option 键名):
| 配置项 |
动态模式默认 |
伪静态模式默认 |
控制器 |
rule_index |
?page={%page%} |
/page/{%page%}/ |
首页列表 |
rule_article |
?article={%id%} |
/article/{%id%}.html |
文章详情 |
rule_page |
?id={%id%} |
/{%alias%}.html |
独立页面 |
rule_category |
?category={%id%}&page={%page%} |
/category/{%alias%}/{%page%}/ |
分类列表 |
rule_tag |
?tags={%tag%}&page={%page%} |
/tags-{%tag%}_{%page%}.html |
标签列表 |
rule_record |
?record={%record%}&page={%page%} |
/date/{%record%}/{%page%}/ |
微语/归档 |
规则中可使用占位符,生成链接时由 Url 类替换(system/lib/http/url.php)。
常用占位符
| 占位符 |
说明 |
{%host%} |
站点 URL(SITE_URL) |
{%id%} |
数字 ID |
{%alias%} |
别名(无别名时回退为 ID) |
{%page%} |
分页页码 |
{%tag%} |
标签名 |
{%category%} / {%sortname%} / {%sort_alias%} |
分类相关 |
{%year%} / {%month%} / {%day%} |
文章发布日期 |
分页占位符 {%page%} 在生成非分页链接时会被 Url::buildFromRule() 自动剔除。
内置路由一览
除可配置的内容路由外,系统还内置 活动路由(type = active),在三种 linkmode 下均参与匹配:
| 路径 / 参数 |
控制器 |
说明 |
?author=1 |
Author_Controller |
作者页 |
?keyword=关键词 |
Search_Controller |
搜索 |
/user 或 ?user |
User_Controller::index |
个人中心 |
/login 或 ?login |
User_Controller::login |
登录 |
/register 或 ?register |
User_Controller::register |
注册 |
/auth_api 或 ?auth_api |
User_Controller::authApi |
认证 API |
?rest-api=方法名 |
Api_Controller |
REST API |
/plugin/插件名 或 ?plugin=插件名 |
Plugin_Controller |
插件前台页 |
?resource_alias=别名 |
Download_Controller |
附件下载 |
POST ?action=addcom |
Comment_Controller |
提交评论 |
POST ?action=... |
Like_Controller |
点赞 |
伪静态模式下用户相关路径示例:
/user
/login
/register
/auth_api
/plugin/video
动态模式下对应为:
?user
?login
?register
?auth_api
?plugin=video
请求匹配流程
flowchart TD
A[浏览器请求] --> B[Web 服务器重写到 index.php]
B --> C[Dispatcher::setPath 解析路径]
C --> D[Option::getRoutingTable 获取路由表]
D --> E[按优先级匹配 pattern]
E --> F[校验 must_get / GET 参数]
F --> G[setMatchedRoute 写入 $_GET]
G --> H[Controller 方法执行]
要点:
Dispatcher::setPath() 从 REQUEST_URI 取 path,并去掉 SITE_URL 中的子目录前缀
- 伪静态模式跳过纯 query 型内容路由;动态模式跳过纯 path 型 rewrite 路由
- 活动路由排在默认首页路由之前,避免
?category=1 被首页抢走
- 插件可通过
HopeHooks::ROUTING_REGISTER 向路由表头部追加规则
Web 服务器配置
使用 伪静态(linkmode=1) 或 index.php 式(linkmode=2) 时,需将不存在的文件/目录请求转发到 index.php。
Apache(站点根目录)
在 index.php 同级创建或编辑 .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
</IfModule>
若安装在子目录(如 /hopecms/),将 RewriteBase 改为 /hopecms/。
Nginx
location / {
try_files $uri $uri/ /index.php?$query_string;
}
index.php 式(linkmode=2) 若 try_files 无效,可改用:
location / {
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php/$1 last;
}
}
IIS
需安装 URL Rewrite 模块,将请求重写到 index.php。Hope CMS 已兼容 HTTP_X_REWRITE_URL 头。
修改服务器配置后,先在后台确认 linkmode 与 URL 规则已保存,再访问文章、分类、用户中心等链接逐项测试。
生成链接(开发)
主题与插件应使用 Url 类或 hope_resolve_user_url(),不要手写路径:
Url::log($gid); // 文章/页面
Url::sort($sid); // 分类
Url::tag($tagname); // 标签
Url::logPage(); // 首页分页
Url::userCenter(['api' => 1]); // 个人中心 API
Url::plugin('video', ['vid' => 1]); // 插件页(动态模式带 query)
Url::plugin() 在伪静态下生成 /plugin/video?vid=1,在动态下生成 ?plugin=video&vid=1。
插件扩展伪静态
插件在站点 已开启 linkmode 1 或 2 时,可注册独立 path 规则。标准步骤:
- 新建
{插件名}_rewrite.php,实现 xxx_register_rewrite_routes($table, &$routes)
- 在插件入口
addAction(HopeHooks::ROUTING_REGISTER, 'xxx_register_rewrite_routes')
- 可选:提供
processor 回调,将路径参数写入 $_GET
以 视频扩展插件 为例(content/plugin/video/video_rewrite.php):
| URL 示例 |
含义 |
/video |
视频列表 |
/video/12 |
视频详情(ID) |
/video/slug/别名 |
按别名访问 |
/video/cat/1 |
分类列表 |
/video/cat/1/page/2 |
分类分页 |
核心注册代码:
function video_register_rewrite_routes($table, &$routes) {
if (!video_is_active() || !video_use_rewrite_urls()) {
return;
}
$p = preg_quote(video_rewrite_prefix(), '#');
$newRoutes = [
[
'type' => 'rewrite',
'model' => 'Plugin_Controller',
'method' => 'loadPluginShow',
'pattern' => "/{$p}/{%vid&type=num%}",
'processor' => 'video_route_processor',
'route_key' => 'vid',
'request_method' => '',
],
// ... 其余列表、分类、slug 规则
];
// 插入到路由表前部,优先于内容路由匹配
$routes = array_merge($newRoutes, $routes);
}
video_use_rewrite_urls() 典型判断:
function video_use_rewrite_urls() {
$cfg = video_get_config();
if (($cfg['rewrite'] ?? 'y') !== 'y') {
return false;
}
$linkmode = (string) Option::get('linkmode');
return $linkmode === '1' || $linkmode === '2';
}
路由项字段说明
| 字段 |
说明 |
type |
rewrite(path)、query(动态 query)、active(活动路由) |
model / method |
控制器类名(不含 _Controller 后缀)与方法 |
pattern |
匹配模式,支持 {%param%}、{%param&type=num%} |
must_get |
必须存在的 $_GET 键 |
args |
捕获组到参数名的映射,如 category@alias |
processor |
匹配成功后的参数处理回调 |
request_method |
限制 GET / POST,空表示不限制 |
prefix |
路由前缀,命中时自动设置 $_GET[prefix] |
路由 pattern 中的类型修饰:
| 写法 |
含义 |
{%id%} |
任意非 / 字符 |
{%id&type=num%} |
仅数字 |
{%slug&type=alnum%} |
字母数字 |
钩子扩展
addAction(HopeHooks::ROUTING_REGISTER, 'myplugin_register_routes');
function myplugin_register_routes($table, &$routes) {
$routes = array_merge([
[
'type' => 'rewrite',
'model' => 'Plugin_Controller',
'method' => 'loadPluginShow',
'pattern' => '/myplugin/{%id&type=num%}',
'processor' => function ($params, $route) {
$_GET['plugin'] = 'myplugin';
$params['plugin'] = 'myplugin';
return $params;
},
],
], $routes);
}
完整挂载点说明见 挂载点手册。
常见问题
开启伪静态后全部 404
- 检查 Web 服务器是否将请求重写到
index.php
- 子目录安装时确认
RewriteBase 或 SITE_URL 配置正确
- 确认
linkmode 为 1 或 2 且规则已保存
首页正常,文章/分类 404
- 检查
rule_article、rule_category 等是否与服务器重写兼容
- 自定义规则勿遗漏必要占位符(如
{%id%}、{%alias%})
- 清除
content/cache/ 下缓存后重试
插件伪静态不生效
- 站点
linkmode 必须为 1 或 2
- 插件设置中需开启「启用伪静态 URL」
- 确认
routing_register 钩子已注册且插件已启用
- 路由
pattern 比系统路由更具体时,应通过 array_merge($newRoutes, $routes) 插到表头
动态模式下用户中心 API 异常
- 个人中心 API:
?user&api=1&action=profile
- 认证 API 专用路由
/auth_api(或 ?auth_api),无需依赖 ?api=1 也可进入处理逻辑
- 生成链接时使用
Url::userCenter()、Url::authApi(),不要硬编码
相关文件
| 文件 |
职责 |
system/lib/core/option.php |
路由表生成、linkmode 切换 |
system/lib/http/dispatcher.php |
路径解析与路由匹配 |
system/lib/http/url.php |
按规则生成前台链接 |
system/lib/hooks.php |
HopeHooks::ROUTING_REGISTER |
content/admin/setting.php |
后台链接配置界面 |
API 开发文档
Hope CMS 提供 REST 风格接口,通过 URL 参数 rest-api 指定方法名。响应均为 JSON。
基础地址
http://www.hopecms.cn/?rest-api={方法名}
示例:
GET http://www.hopecms.cn/?rest-api=article_list&page=1&count=10
开关
除支付相关接口外,其余 API 需在后台开启 OpenAPI(Option::get('is_openapi') !== 'n'),否则返回 api is closed。
支付接口(pay_notify、pay_create、pay_cashier、pay_status)不受此限制。
鉴权方式
需要鉴权的接口(如发文、上传)支持两种方式:
1. API Key 签名(服务端 / 第三方调用)
后台「设置 → API」获取 apikey,请求携带:
| 参数 |
说明 |
req_time |
当前 Unix 时间戳(与服务器时差 ≤ 300 秒) |
req_nonce |
必填,16–64 位十六进制随机串,防重放 |
req_sign |
md5(req_time + req_nonce + apikey) |
$req_time = time();
$req_nonce = bin2hex(random_bytes(16));
$apikey = '你的apikey';
$req_sign = md5($req_time . $req_nonce . $apikey);
POST http://www.hopecms.cn/?rest-api=article_post&req_time=1710000000&req_nonce=abc...&req_sign=xxxx
缺少参数、签名错误或 nonce 重放时返回 auth param error / sign error / nonce required / replay detected。
2. 登录 Cookie(浏览器端)
已登录管理员/用户携带站点认证 Cookie(AUTH_COOKIE_NAME)时,可免 API Key,且 author_uid 自动取当前用户。
响应格式
成功:
{ "code": 200, "msg": "ok", "data": { ... } }
失败:
{ "code": 0, "msg": "错误说明" }
认证失败:code 为 401。
鉴权失败使用 Output::authError,HTTP 状态码与 code 字段以实际返回为准。
文章接口
article_list — 文章列表
GET ?rest-api=article_list
| 参数 |
类型 |
说明 |
page |
int |
页码,默认 1 |
count |
int |
每页条数,默认跟随首页设置 |
sort_id |
int |
分类 ID |
keyword |
string |
标题关键词 |
tag |
string |
标签名 |
order |
string |
views / comnum,默认按置顶与时间 |
返回 data.articles 数组,含 id、title、cover、url、date、author_name、tags 等。
article_detail — 文章详情
GET ?rest-api=article_detail&id=1
密码保护文章返回错误。成功返回 data.article。
article_post — 发布文章
POST ?rest-api=article_post
需鉴权。主要 POST 字段:
| 字段 |
说明 |
title |
标题(必填) |
content |
正文(必填) |
excerpt |
摘要 |
sort_id |
分类 ID |
tags |
标签,逗号分隔 |
cover |
封面 URL |
draft |
y 草稿 / n 发布 |
alias |
别名 |
top / sortop |
置顶 / 分类置顶 |
allow_remark |
是否允许评论 |
password |
阅读密码 |
template |
自定义模板 |
article_update — 更新文章
POST ?rest-api=article_update
需鉴权。需传 id 及要更新的字段。
分类与微语
| 接口 |
方法 |
说明 |
sort_list |
GET |
分类列表 |
note_list |
GET |
微语列表 |
note_post |
POST |
发布微语(需鉴权) |
评论与用户
| 接口 |
方法 |
说明 |
comment_list |
GET |
文章评论,id 为文章 ID |
userinfo |
GET |
当前登录用户信息(需 Cookie 鉴权) |
个人中心 API
前台个人中心通过 ?user&api=1(或伪静态路径 /user?api=1)调用,需登录 Cookie。POST 请求须携带页面输出的 token 参数(与 Session Token 校验)。链接模式说明见 伪静态与路由。
GET http://www.hopecms.cn/?user&api=1&action=profile
POST http://www.hopecms.cn/?user&api=1
Body: token=...&action=profile&nickname=...
| action |
方法 |
说明 |
profile |
GET / POST |
读取或更新个人资料 |
avatar_upload |
POST |
上传头像,avatar 文件字段 |
avatar_qq |
POST |
使用 QQ 头像,字段 qq |
recharge |
POST |
创建充值订单 |
recharge_records |
GET |
充值记录,支持 page、per_page |
invite_info |
GET |
邀请码与奖励统计 |
forum_posts |
GET |
我的论坛文章,返回含 url |
forum_get |
GET |
单篇论坛文章,id |
forum_save |
POST |
发布或更新论坛文章 |
forum_delete |
POST |
删除论坛文章,id |
forum_sorts |
GET |
可选论坛分类 |
my_comments |
GET |
我的评论,含 comment_url 锚点 |
comment_reply |
POST |
回复评论,pid、content |
my_media |
GET |
我的媒体库 |
media_upload |
POST |
上传媒体 |
media_delete |
POST |
删除媒体,id |
业务实现位于 system/app/service/user_center.php。主题可在 user/ 目录下提供个人中心模板,并通过 js/user_center.js 对接 API。
插件可通过挂载点 HopeHooks::USER_CENTER_API 扩展自定义 action。
媒体上传
POST ?rest-api=upload
需 API Key 鉴权。multipart/form-data 字段:
| 字段 |
说明 |
file |
文件 |
sid |
分类 ID(可选) |
author_uid |
作者 UID,默认 1 |
成功返回 media_id、url、file_info。
支付接口
由 Pay_Controller 处理,不依赖 OpenAPI 开关。常用于收银台与异步通知:
| 接口 |
说明 |
pay_create |
创建支付订单 |
pay_cashier |
收银台页面数据 |
pay_status |
查询订单状态 |
pay_notify |
支付平台异步回调(由网关服务器调用) |
网关密钥、回调 URL 等在后台 支付设置 中配置;主题/插件只负责创建业务订单并跳转收银台。参数与返回值以 system/app/controller/pay_controller.php 及当前支付插件为准,接入前请对照源码与后台说明。
限流:若后台开启了 API 访问限流(设置 → API),超限时返回错误信息,请降低调用频率或调整限额。
调用示例(PHP)
$base = 'http://www.hopecms.cn/';
$req_time = time();
$req_nonce = bin2hex(random_bytes(16));
$apikey = 'your_apikey';
$sign = md5($req_time . $req_nonce . $apikey);
$ch = curl_init($base . '?rest-api=article_list&page=1&count=5&req_time=' . $req_time . '&req_nonce=' . $req_nonce . '&req_sign=' . $sign);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$body = curl_exec($ch);
curl_close($ch);
$data = json_decode($body, true);
扩展 API
优先通过插件扩展,避免直接改核心 Api_Controller(升级会被覆盖):
- 个人中心类:挂载
HopeHooks::USER_CENTER_API(doOnceAction)接管自定义 action
- 独立前台接口:插件
_show.php + 自建鉴权,或注册路由后由插件处理
- 确需 REST 风格:可在插件中于
init 钩子里拦截 rest-api 参数并 Output::ok 后 exit(注意与核心方法名冲突)
若维护私有分支必须改核心:在 Api_Controller 增加 private function your_api(),方法名即 rest-api 值;需鉴权则开头调用 $this->auth() / $this->checkApiKey()。
相关:挂载点手册 · 伪静态与路由 · 插件开发指南