🐝 蜜蜂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; }

// 插件逻辑从此开始...
?>

🏷️ 元信息标签说明

标签必填说明
@Name插件显示名称
@Description功能描述(展示在管理后台)
@Version语义化版本号 x.y.z
@Author推荐作者名
@Requires推荐最低系统版本要求
@Icon可选一个 Emoji 图标,默认 🔌

🔌 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 字符串

📋 注册后台菜单

hook_add('admin_nav_items', function ($items) {
    $items['my_plugin_menu'] = array(
        'href'   => '/admin/plugin/page.php?slug=my-plugin&view=dashboard',
        'icon'   => '📊',
        'title'  => '菜单标题',
        'desc'   => '菜单描述',
        'parent' => 'plugins'  // 归属到"插件"菜单组
    );
    return $items;
});

⚙️ 插件配置管理

系统提供统一配置存储 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);
});
💡 提示:以上代码完全遵循规范,包含CSRF保护、权限检查和Hook机制。