🐝 蜜蜂AI建站 · 插件开发规范 v1.0 | 适用系统 ≥ 0.5.0
零侵入 · Hook驱动 · 轻量灵活 —— 为插件开发者提供标准、安全、高效的扩展体系。
📌 概述
蜜蜂AI建站插件系统采用独立目录与Hook事件机制,开发者只需遵循目录规范和接口约定,即可扩展后台菜单、修改前端输出、存储配置等,无需改动核心代码。所有插件均在沙盒环境下按需加载。
📁 插件目录结构
plugins/
└── your-plugin/ ← 插件目录名即 slug(仅允许字母、数字、连字符、下划线)
├── plugin.php ← 必须 - 入口文件
├── views/ ← 可选 - 后台页面
│ ├── settings.php ← 配置页(自动出现"配置"按钮)
│ └── *.php ← 自定义页面
└── public/ ← 可选 - 前端静态资源(CSS/JS/图片)
├── style.css
└── script.js
⚙️ 入口文件(plugin.php)
入口文件必须包含 docblock 元信息头,并且包含安全检查代码:
<?php
/**
* @Name 插件中文名称
* @Description 插件功能简介(一句话)
* @Version 1.0.0
* @Author 作者名
* @Requires 0.5.0
* @Icon 🔌
*/
// 安全检查:防止直接访问
if (!defined('APP_PATH')) { exit; }
// 插件逻辑从此开始...
?>
🔌 Hook 系统
插件通过Hook与系统交互,零侵入设计。支持Action(执行动作)和Filter(链式过滤)。
// Action Hook(执行动作,无返回值)
hook_add('hook_name', function ($arg1, $arg2) {
// 逻辑
}, 10);
// Filter Hook(必须返回修改后的值)
hook_add('filter_name', function ($value, $extra) {
$value .= '追加';
return $value;
}, 10);
系统内置 Hook
📍 Action Hooks
| Hook 名称 | 触发时机 | 参数 |
|---|---|---|
plugins_loaded | 所有插件加载完毕 | 无 |
plugin_activate_{slug} | 插件被启用时 | 无 |
plugin_deactivate_{slug} | 插件被禁用时 | 无 |
📍 Filter Hooks
| Hook 名称 | 用途 | 参数 |
|---|---|---|
admin_nav_items | 注册后台侧边栏菜单 | $items 数组 |
render_html_output | 修改前端渲染输出 HTML | $html 字符串 |
⚙️ 插件配置管理
系统提供统一配置存储 API,配置以 JSON 保存在运行时配置文件中。
// 读取配置
$config = plugin_get_config('my-plugin');
$apiKey = isset($config['api_key']) ? $config['api_key'] : '';
// 保存配置(覆盖)
plugin_save_config('my-plugin', array('api_key' => 'xxx', 'enabled' => true));
// 部分更新(合并)
plugin_update_config('my-plugin', array('api_key' => 'new-key'));
📄 后台页面(views/)
📌 配置页 settings.php
如果存在 views/settings.php,后台插件卡片会自动显示“配置”按钮。访问URL:/admin/plugin/page.php?slug=your-plugin&view=settings。
代码示例 (settings.php):(完整展示表单及CSRF保护)
<?php
/**
* 我的插件 - 配置页
*/
$activeNav = 'plugins';
$pageTitle = '插件配置';
$cfg = plugin_get_config('my-plugin');
$flashMsg = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
require_csrf();
$newCfg = array(
'api_key' => trim((string)(isset($_POST['api_key']) ? $_POST['api_key'] : '')),
);
plugin_save_config('my-plugin', $newCfg);
$cfg = $newCfg;
$flashMsg = '配置已保存';
}
require __DIR__ . '/../../../app/admin-sidebar.php';
$adminName = isset($_SESSION['admin_name']) ? (string)$_SESSION['admin_name'] : 'Admin';
$adminUsername = isset($_SESSION['admin_username']) ? (string)$_SESSION['admin_username'] : 'admin';
$avatarText = strtoupper(substr($adminName !== '' ? $adminName : 'A', 0, 1));
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title><?php echo e($pageTitle); ?> - <?php echo e(APP_NAME); ?></title>
<link rel="stylesheet" href="/assets/css/admin-ui.css">
</head>
<body>
<div class="admin-shell">
<?php render_admin_sidebar($activeNav, $adminName, $adminUsername, $avatarText); ?>
<main class="admin-content">
<div class="content-wrap">
<h2><?php echo e($pageTitle); ?></h2>
<?php if ($flashMsg): ?>
<div class="flash-msg flash-success"><?php echo e($flashMsg); ?></div>
<?php endif; ?>
<form method="POST">
<?php echo csrf_field(); ?>
<div class="input-group">
<span>API Key</span>
<input class="input" type="text" name="api_key"
value="<?php echo e(isset($cfg['api_key']) ? $cfg['api_key'] : ''); ?>">
</div>
<button class="btn-primary" type="submit">保存配置</button>
</form>
</div>
</main>
</div>
</body>
</html>
📌 自定义页面
在 views/ 下创建任意PHP文件,通过 /admin/plugin/page.php?slug=your-plugin&view=custom-page 访问。
🎨 前端静态资源
将 CSS/JS/图片等放在 public/ 目录下,使用系统函数获取 URL。
<?php
$cssUrl = plugin_url('my-plugin') . '/public/style.css';
$jsUrl = plugin_url('my-plugin') . '/public/script.js';
?>
<link rel="stylesheet" href="<?php echo $cssUrl; ?>">
<script src="<?php echo $jsUrl; ?>"></script>
🛠️ 辅助函数表
| 函数 | 说明 |
|---|---|
plugin_url($slug) | 获取插件 URL 路径前缀 |
plugin_path($slug) | 获取插件文件系统绝对路径 |
plugin_get_config($slug) | 获取插件配置数组 |
plugin_save_config($slug, $values) | 保存插件配置(覆盖) |
plugin_update_config($slug, $values) | 部分更新配置(合并) |
plugin_is_enabled($slug) | 判断插件是否已启用 |
hook_add($hook, $callback, $priority) | 注册 Hook |
hook_do($hook, ...$args) | 触发 Action Hook |
hook_filter($hook, $value, ...$args) | 触发 Filter Hook |
e($str) | HTML 转义输出 |
csrf_field() | 输出 CSRF hidden input |
require_csrf() | 验证 POST CSRF token |
require_login() | 要求管理员登录 |
redirect($url) | 302 跳转 |
📦 安装与发布
本地安装: 将插件目录放入 plugins/ 文件夹,或在管理后台点击“上传插件”按钮上传 ZIP 包。
ZIP 打包规范
my-plugin.zip
└── my-plugin/ ← 目录名 = 插件 slug
├── plugin.php
├── views/
└── public/
支持文件类型:php, html, htm, css, js, json, png, jpg, jpeg, gif, svg, webp, ico, txt, md, sql, woff, woff2, ttf, eot, otf
🔄 生命周期
安装 → 启用(plugin_activate_{slug}) → 运行(plugin_load_all) → 禁用(plugin_deactivate_{slug}) → 删除
- 启用:系统 require 入口文件并触发
plugin_activate_{slug} - 运行:每次请求时加载已启用插件的入口文件
- 禁用:从启用列表移除并触发
plugin_deactivate_{slug} - 删除:先禁用,再删除配置和文件目录
✨ 最佳实践
- 🔐 安全第一:入口文件开头加
if (!defined('APP_PATH')) { exit; } - 🧩 命名空间:函数名以插件slug为前缀(如
myplugin_do_something()) - ✅ 配置验证:保存配置前做类型检查和默认值处理
- 🛡️ 优雅降级:Hook回调使用 try-catch,避免影响主系统
- ⚡ CSRF保护:所有POST表单必须调用
require_csrf()验证 - 📦 版本兼容:使用
@Requires声明最低系统版本 - 🌐 资源路径:使用
plugin_url()而非硬编码 - 🚫 不要修改核心文件:所有功能通过 Hook 实现
🧪 示例插件模板
最小可运行插件,在前端页面底部注入文字:
<?php
/**
* @Name Hello World
* @Description 一个最简示例插件
* @Version 1.0.0
* @Author 开发者
* @Icon 👋
*/
if (!defined('APP_PATH')) { exit; }
// 在所有前端页面底部添加一段文字
hook_add('render_html_output', function ($html) {
$inject = '<div style="text-align:center;padding:10px;color:#999;font-size:12px;">Powered by Hello World Plugin</div>';
return str_ireplace('</body>', $inject . '</body>', $html);
});