插件目录结构
public/plugins/my-plugin/
├── config.json # 插件配置(必须)
├── hooks.php # 钩子注册
├── install.php # 安装脚本
├── uninstall.php # 卸载脚本
├── admin.php # 后台页面
├── api.php # API接口
└── static/ # 静态资源
config.json 配置
{
"name": "插件名称",
"app_id": "plugin-slug",
"version": "1.0.0",
"description": "插件描述",
"author": "作者",
"type": 1,
"system_requirement": "FmBlog v1.0.0以上",
"php_version": "7.4+",
"is_system": 0,
"preview": "preview.jpg",
"hooks": ["admin_menu", "admin_route"],
"config": {
"option1": "value1"
}
}
| 字段 | 必填 | 说明 |
|---|---|---|
| name | ✅ | 插件名称 |
| app_id | ✅ | 插件标识(字母数字下划线短横线) |
| version | ✅ | 版本号 (x.y.z) |
| type | ❌ | 1=插件, 2=主题 |
| preview | ❌ | 预览图路径 |
| hooks | ❌ | 注册的钩子列表 |
| config | ❌ | 默认配置对象 |
| is_system | ❌ | 1=系统插件不可卸载 |
| system_requirement | ❌ | 系统要求 |
| php_version | ❌ | PHP版本要求 |
安装脚本 install.php
function plugin_install()
{
global $db;
// 创建数据表
$db->query("CREATE TABLE IF NOT EXISTS fm_myplugin_data (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
)");
return true;
}
注册后台菜单 hooks.php
// 注册后台菜单
Hook::add('admin_menu', function($menu) {
$menu['功能扩展'][] = [
'我的插件',
'?a=myplugin',
'layui-icon-component',
'admin'
];
return $menu;
});
// 注册后台路由
Hook::add('admin_route', function($routeMap) {
$routeMap['myplugin'] = 'myplugin_index';
return $routeMap;
});
后台页面开发
在 admin.php 中创建后台页面函数:
function myplugin_index()
{
global $db;
fmblog_title('我的插件', '插件管理页面');
// 处理表单提交
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = post('action');
// 处理逻辑...
}
// 渲染页面
include 'views/header.php';
// 页面内容...
include 'views/footer.php';
}
API 接口开发
在 api/ 目录下创建接口文件,如 api/myplugin.php:
// api/myplugin.php
// 函数命名格式: api_{模块}_{动作}
// 调用方式: api.php?m=myplugin&a=list
function api_myplugin_list()
{
global $db;
api_check_login();
$list = $db->name('myplugin_data')->select();
api_json_success(['list' => $list]);
}
function api_myplugin_add()
{
global $db;
api_check_post();
$name = post('name', '');
if (empty($name)) {
api_json_error('名称不能为空');
}
$id = $db->name('myplugin_data')->insert([
'name' => $name,
'create_time' => date('Y-m-d H:i:s')
]);
api_json_success(['id' => $id], '添加成功');
}
function api_myplugin_delete()
{
global $db;
api_check_login();
$id = intval(get('id', 0));
if ($id <= 0) {
api_json_error('ID无效');
}
$db->name('myplugin_data')->where('id', $id)->delete();
api_json_success(null, '删除成功');
}
调用示例:
// 获取列表
GET /api.php?m=myplugin&a=list
// 添加数据
POST /api.php?m=myplugin&a=add
Body: {"name": "测试"}
// 删除数据
GET /api.php?m=myplugin&a=delete&id=1
常用钩子列表
| 钩子名称 | 说明 | |
|---|---|---|
| admin_menu | 注册后台菜单 | |
| admin_route | 注册后台路由 | |
| article_add_before | 文章添加前 | |
| article_add_after | 文章添加后 | |
| article_edit_before | 文章编辑前 | |
| article_edit_after | 文章编辑后 | |
| article_delete_before | 文章删除前 | |
| article_delete_after | 文章删除后 | |
| cate_add_after | 分类添加后 | |
| cate_edit_after | 分类编辑后 | |
| cate_delete_after | 分类删除后 | |
| theme_switch_before | 主题切换前 | |
| theme_switch_after | 主题切换后 | |
| 应用商店相关 | ||
| app_store_install_before | 应用安装前 | |
| app_store_install_after | 应用安装后 | |
| app_store_uninstall_before | 应用卸载前 | |
| app_store_uninstall_after | 应用卸载后 | |
| 单页相关 | ||
| page_add_after | 单页添加后 | |
| page_edit_after | 单页编辑后 | |
| page_delete_after | 单页删除后 | |