开发文档

了解如何使用 EchoX 开放平台

插件开发指南

更新时间:2026-09-11 11:16 | 浏览次数:65 次

开发者开发第三方插件(非官方插件)需要进行以下声明:

EchoX 开放平台第三方插件开发者声明

本人 / 本团队(以下统称 “开发者”)自愿在 EchoX 开放平台(open.echox.cc,以下简称 “平台”)开发、发布、运营第三方插件(非官方插件,以下简称 “插件”),并郑重作出如下声明:

一、合规开发承诺

  1. 开发者承诺严格遵守《中华人民共和国网络安全法》《中华人民共和国个人信息保护法》《互联网信息服务管理办法》等国家法律法规及平台发布的《EchoX 开放平台隐私政策》《EchoX 开放平台服务条款》《第三方插件开发规范》等所有规则,插件开发、发布、运营全程合法合规,不违反公序良俗。
  2. 开发者承诺插件功能与描述一致,不开发、发布虚假功能、恶意诱导、违规引流类插件,不利用插件从事任何违法违规活动(如传播色情、暴力、赌博、反动信息,窃取用户信息,实施网络攻击等)。

二、知识产权承诺

  1. 开发者承诺对所开发插件拥有完整、合法的知识产权(包括但不限于版权、专利权、商标权等),或已获得知识产权权利人的明确授权,插件内容不存在抄袭、盗用、篡改他人作品 / 代码的情形。
  2. 若插件使用第三方开源代码 / 组件,开发者承诺遵守对应开源协议,已获得合法使用权限,不侵犯开源作者及相关方权益。
  3. 因插件知识产权侵权引发的一切纠纷(包括但不限于投诉、诉讼、赔偿),由开发者独立承担全部责任,与 EchoX 开放平台无关;平台因此遭受损失的,开发者需全额赔偿。

三、安全保障承诺

  1. 开发者承诺插件不含任何恶意代码(如病毒、木马、挖矿程序、后门程序等),不窃取、泄露、倒卖用户及平台的任何数据(包括但不限于用户账号、手机号、身份证号、论坛内容、平台接口数据等)。
  2. 开发者承诺插件仅收集实现核心功能所必需的信息,且收集、使用用户信息前已获得用户明确同意,严格遵守平台隐私政策要求,不超范围收集、滥用用户信息。
  3. 开发者承诺及时修复插件存在的安全漏洞,若因插件安全问题导致用户 / 平台数据泄露、设备受损、财产损失等,由开发者独立承担全部赔偿责任。

四、责任划分承诺

  1. 插件的开发、测试、发布、售后、运营等全流程由开发者独立负责,插件使用过程中产生的一切问题(包括但不限于功能异常、数据错误、兼容性问题、用户损失等),均由开发者承担全部责任,EchoX 开放平台不承担任何连带责任。
  2. 开发者承诺向插件使用者提供清晰的使用说明、售后联系方式,及时响应并解决用户的咨询、投诉、问题反馈,保障插件正常使用。
  3. 若插件涉及付费、变现等行为,开发者承诺收费标准透明、合理,不欺诈、误导用户,交易纠纷由开发者与用户自行协商解决,平台仅提供技术对接支持,不介入纠纷处理。

五、平台规则遵守承诺

  1. 开发者承诺接受 EchoX 开放平台对插件的审核、监管、抽检,配合平台完成插件合规性、安全性检测,若平台发现插件违反本声明或平台规则,开发者同意平台采取下架插件、冻结开发者账号、没收收益等措施。
  2. 开发者承诺未经平台允许,不使用 “EchoX 官方”“EchoX 认证” 等易误导用户的标识,不宣称插件与平台存在官方合作关系。
  3. 开发者承诺插件下架 / 停止运营前,提前 7 个工作日通知插件使用者,妥善处理用户已付费、未到期服务等问题,保障用户合法权益。

六、免责声明

开发者确认,EchoX 开放平台仅提供插件展示、分发的技术服务,不对第三方插件的合法性、安全性、功能性、可用性做任何明示或默示的担保;因使用第三方插件导致的任何损失,均与平台无关。

七、其他

  1. 本声明自开发者在平台提交第三方插件审核之日起生效,对开发者及所开发的所有第三方插件均具有约束力。
  2. 若开发者违反本声明,平台有权终止开发者的入驻资格,下架全部插件,并保留追究开发者法律责任的权利。
  3. 本声明未尽事宜,按照 EchoX 开放平台相关规则及国家法律法规执行。

开发者(签字):XXX

开发者账号 / 团队名称 (EchoX开放平台用户名):XXX

联系电话:XXX

日期:XX年X月X日


EchoX 论坛插件开发文档


===========================================================================

概述

===========================================================================

EchoX 论坛支持插件扩展机制,允许开发者在不修改核心代码的情况下扩展论坛功能。


===========================================================================

插件目录结构

===========================================================================

plugins/

└── 你的插件名称/ # 插件目录(英文,首字母大写)

├── plugin.json # 插件配置文件(必需)

├── hook.php # 插件钩子文件(可选)

└── ... # 其他文件(页面、CSS、JS等)


===========================================================================

快速开始

===========================================================================

1. 创建插件目录

在 plugins/ 目录下创建你的插件文件夹,例如:MyPlugin


2. 编写 plugin.json

{

"name": "我的插件",

"identifier": "MyPlugin",

"version": "1.0.0",

"author": "你的名字",

"description": "插件的简短描述"

}


3. 编写 hook.php(可选)

如果你需要在特定时机执行代码(如页面加载时),创建 hook.php 文件。


4. 创建插件页面(可选)

如果插件需要独立页面(如好友系统),可以在插件目录下创建 PHP 文件。


===========================================================================

配置文件说明

===========================================================================

plugin.json 字段说明:

| 字段 | 类型 | 必填 | 说明 |

|--------------|----------|------|----------------------------------------|

| name | string | 是 | 插件显示名称 |

| identifier | string | 是 | 插件唯一标识符(英文,与目录名一致) |

| version | string | 是 | 插件版本号,如 "1.0.0" |

| author | string | 否 | 作者名称 |

| description | string | 否 | 插件描述 |


===========================================================================

可用钩子点

===========================================================================

1. page_header - 页面头部

触发时机: 每个页面加载时,在 <body> 开始后

适用场景: 插入全局CSS、JS、顶部导航等

可用变量: 所有系统变量

调用位置: templates/header.php, mobile/includes/header.php


2. page_footer - 页面底部

触发时机: 每个页面结束前,在 </body> 前

适用场景: 插入统计代码、底部脚本、浮动按钮等

可用变量: 所有系统变量

调用位置: templates/footer.php, mobile/includes/footer.php


3. user_profile_sidebar - 用户个人中心侧边栏

触发时机: 用户个人中心页面加载时

适用场景: 添加个人中心功能区块

额外变量:

- $viewUserId - 被查看用户的ID

- $viewUser - 被查看用户的信息

调用位置: user.php


4. post_before_content - 帖子内容前

触发时机: 帖子详情页,帖子内容显示前

适用场景: 插入广告、提示信息等

额外变量:

- $post - 帖子信息数组

调用位置: post.php


5. post_after_content - 帖子内容后

触发时机: 帖子详情页,帖子内容显示后

适用场景: 插入分享按钮、相关推荐等

额外变量:

- $post - 帖子信息数组

调用位置: post.php


6. home_content - 首页内容区

触发时机: 首页加载时

适用场景: 添加首页功能区块

额外变量:

- $categories - 板块列表

- $latestPosts - 最新帖子

调用位置: index.php


7. mobile_user_card - 手机版用户卡片

触发时机: 手机版用户个人页面,用户信息卡片区域

适用场景: 在用户头像、用户名下方显示额外信息(如积分、等级等)

额外变量:

- $currentUser - 当前登录用户

- $viewUser - 被查看的用户

- $isOwnProfile - 是否查看自己的主页

- $wearingMedals - 佩戴的勋章列表

调用位置: mobile/user.php


8. mobile_user_functions - 手机版我的功能

触发时机: 手机版"我的"页面,功能菜单网格区域

适用场景: 添加功能图标按钮(如签到、任务中心等)

额外变量:

- $currentUser - 当前登录用户

- $viewUser - 被查看的用户

- $isOwnProfile - 是否查看自己的主页

调用位置: mobile/user.php

示例代码:

<?php

// 在手机版"我的功能"区域添加签到按钮

if ($hookPoint !== 'mobile_user_functions') {

return;

}

if (!$isOwnProfile) {

return; // 只在查看自己主页时显示

}

?>

<a href="/plugins/SignIn/sign.php" class="mobile-menu-item">

<div class="mobile-menu-icon" style="background: #ffebee; color: #f44336;">

<i class="fas fa-calendar-check"></i>

</div>

<span>每日签到</span>

</a>


9. mobile_user_account - 手机版账号管理

触发时机: 手机版"我的"页面,账号管理列表区域

适用场景: 添加账号管理选项(如安全设置、隐私设置等)

额外变量:

- $currentUser - 当前登录用户

- $viewUser - 被查看的用户

- $isOwnProfile - 是否查看自己的主页

调用位置: mobile/user.php

示例代码:

<?php

// 在账号管理列表添加选项

if ($hookPoint !== 'mobile_user_account') {

return;

}

?>

<a href="/plugins/MyPlugin/security.php" class="mobile-menu-list-item">

<i class="fas fa-shield-alt" style="color: #4caf50;"></i>

<span>安全中心</span>

<i class="fas fa-chevron-right" style="margin-left: auto; color: #ccc;"></i>

</a>


10. mobile_user_footer - 手机版用户页面底部

触发时机: 手机版用户页面底部,所有内容之后

适用场景: 添加统计信息、广告、额外说明等

额外变量:

- $currentUser - 当前登录用户

- $viewUser - 被查看的用户

- $isOwnProfile - 是否查看自己的主页

调用位置: mobile/user.php


===========================================================================

系统变量列表

===========================================================================

在 hook.php 中可以直接使用以下变量:


【基础变量】

| 变量名 | 类型 | 说明 |

|--------------|----------|----------------------------------------|

| $hookPoint | string | 当前钩子点名称 |

| $siteUrl | string | 网站URL |

| $db | object | 数据库实例 |

| $user | array/null | 当前登录用户信息 |


【用户相关】

| 变量名 | 类型 | 说明 |

|--------------|----------|----------------------------------------|

| $isLoggedIn | bool | 是否已登录 |

| $isAdmin | bool | 是否管理员 |

| $isSuperAdmin| bool | 是否超级管理员 |

| $userId | int | 当前用户ID |


【请求相关】

| 变量名 | 类型 | 说明 |

|--------------|----------|----------------------------------------|

| $currentUrl | string | 当前完整URL |

| $requestMethod| string | HTTP方法 (GET/POST) |

| $getParams | array | GET参数数组 |

| $postParams | array | POST参数数组 |

| $requestUri | string | 请求URI |

| $userAgent | string | 用户浏览器标识 |

| $userIp | string | 用户IP地址 |


【页面信息】

| 变量名 | 类型 | 说明 |

|--------------|----------|----------------------------------------|

| $pageTitle | string | 页面标题 |

| $isMobile | bool | 是否移动端 |

| $currentPage | array | 当前页面信息(type, filename, path等) |


【论坛统计】

| 变量名 | 类型 | 说明 |

|--------------|----------|----------------------------------------|

| $siteStats | array | 站点统计(userCount, postCount, replyCount等) |


===========================================================================

插件管理函数

===========================================================================

【插件检查】

- isPluginEnabled($identifier) - 检查插件是否启用


【用户相关】

- getCurrentUser() - 获取当前登录用户

- isLoggedIn() - 检查是否已登录

- isAdmin() - 检查是否为管理员

- isSuperAdmin() - 检查是否为超级管理员


【数据库操作】

- db() - 获取数据库实例

- db()->query($sql, $params) - 查询多条记录

- db()->queryOne($sql, $params) - 查询单条记录

- db()->execute($sql, $params) - 执行SQL


【工具函数】

- e($string) - HTML转义

- redirect($url) - 页面跳转

- setFlashMessage($type, $message) - 设置提示消息

- getFlashMessage() - 获取提示消息

- formatTime($time) - 格式化时间

- truncate($string, $length) - 截取字符串

- show404Page($message) - 显示404页面


===========================================================================

开发示例

===========================================================================

示例 1:页面底部添加浮动按钮

-------------------------------------------

plugins/FloatButton/plugin.json:

{

"name": "浮动按钮",

"identifier": "FloatButton",

"version": "1.0.0",

"author": "开发者",

"description": "在页面底部添加返回顶部按钮"

}


plugins/FloatButton/hook.php:

<?php

// 只在页面底部钩子执行

if ($hookPoint !== 'page_footer') {

return;

}

?>

<style>

.back-to-top {

position: fixed;

bottom: 30px;

right: 30px;

width: 50px;

height: 50px;

background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);

border-radius: 50%;

display: flex;

align-items: center;

justify-content: center;

color: #fff;

cursor: pointer;

box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);

z-index: 999;

}

</style>

<a href="#" class="back-to-top" onclick="window.scrollTo({top: 0, behavior: 'smooth'}); return false;">

<i class="fas fa-arrow-up"></i>

</a>


示例 2:帖子内容后添加分享按钮

-------------------------------------------

plugins/ShareButtons/plugin.json:

{

"name": "分享按钮",

"identifier": "ShareButtons",

"version": "1.0.0",

"author": "开发者",

"description": "在帖子后添加社交分享按钮"

}


plugins/ShareButtons/hook.php:

<?php

// 只在帖子内容后钩子执行

if ($hookPoint !== 'post_after_content') {

return;

}

?>

<div class="share-buttons" style="margin-top: 20px; padding-top: 20px; border-top: 1px solid #eee;">

<span style="color: #666; margin-right: 10px;">分享到:</span>

<a href="https://service.weibo.com/share/share.php?url=<?php echo urlencode($currentUrl); ?>" target="_blank" class="btn btn-sm" style="background: #e6162d; color: #fff;">

<i class="fab fa-weibo"></i> 微博

</a>

<a href="https://connect.qq.com/widget/shareqq/index.html?url=<?php echo urlencode($currentUrl); ?>&title=<?php echo urlencode($post['title']); ?>" target="_blank" class="btn btn-sm" style="background: #12b7f5; color: #fff;">

<i class="fab fa-qq"></i> QQ

</a>

</div>


示例 3:带独立页面的插件(好友系统)

-------------------------------------------

参考 plugins/Friends/ 目录下的完整实现。


===========================================================================

插件页面开发

===========================================================================

如果插件需要独立页面(如好友系统、商城等):

1. 在插件目录下创建 PHP 文件(如 friends.php)

2. 文件开头检查插件是否启用:

<?php

require_once __DIR__ . '/../../includes/functions.php';


// 检查插件是否启用

if (!isPluginEnabled('YourPlugin')) {

show404Page('该功能已禁用');

}


// 检查是否登录(如需要)

if (!isLoggedIn()) {

redirect(SITE_URL . '/login.php');

}


// 页面逻辑...

?>


3. 引入CSS(如果需要):

<?php

echo '<link rel="stylesheet" href="' . SITE_URL . '/plugins/YourPlugin/style.css">';

?>


===========================================================================

插件安装流程

===========================================================================

1. 开发插件

- 创建插件目录

- 编写 plugin.json

- 编写 hook.php(如有需要)

- 创建插件页面(如有需要)


2. 上传插件

- 将插件文件夹上传到 plugins/ 目录


3. 数据库安装(如需要)

- 创建 install.sql 或 install.php

- 运行安装脚本创建表


4. 后台安装

- 登录管理后台

- 进入"插件管理"

- 在"可用插件"中找到你的插件

- 点击"安装"


5. 启用插件

- 在"已安装插件"中找到你的插件

- 点击"启用"


===========================================================================

⚠️ 重要注意事项

===========================================================================

1. 函数重复定义问题(重要!)

问题: 同一个页面可能多次调用 load_plugins(),导致 hook.php 被多次包含。

后果: 如果定义了 PHP 函数,会出现 "Cannot redeclare function" 致命错误。

解决方案: 所有 PHP 函数必须用 function_exists() 包裹:

// ❌ 错误写法 - 会导致重复定义错误

function myPluginFunction() {

// ...

}


// ✅ 正确写法 - 防止重复定义

if (!function_exists('myPluginFunction')) {

function myPluginFunction() {

// ...

}

}

推荐做法:

- 如果不需要定义 PHP 函数,直接在 hook.php 中输出 HTML/CSS/JS

- 如果需要定义函数,确保使用 function_exists() 检查


2. 钩子点判断

推荐做法: 在 hook.php 开头判断当前钩子点:

// 方法1: 只在特定钩子执行

if ($hookPoint !== 'page_footer') {

return;

}


// 方法2: 支持多个钩子

if (!in_array($hookPoint, ['page_header', 'page_footer'])) {

return;

}


// 方法3: switch 语句处理不同钩子

switch ($hookPoint) {

case 'page_header':

// ...

break;

case 'page_footer':

// ...

break;

}


3. 防止直接访问

推荐做法: 在 hook.php 开头检查变量是否存在:

<?php

// 防止直接访问

if (!isset($hookPoint)) {

return;

}


// 或者

if (!defined('SITE_URL')) {

exit('Access Denied');

}

?>


4. 路径处理

问题: 插件内部引用文件时,路径可能不正确。

解决方案:

<?php

// ✅ 正确做法 - 使用动态计算路径

$pluginUrl = '/plugins/YourPlugin';

// 或者使用 SITE_URL 常量

$pluginUrl = SITE_URL . '/plugins/YourPlugin';


// 引用JS文件

<script src="<?php echo $pluginUrl; ?>/script.js"></script>


// 引用API接口

fetch('<?php echo $pluginUrl; ?>/api/something.php')

?>


5. 插件禁用保护

问题: 插件被禁用后,直接访问插件页面会报错。

解决方案: 在插件页面开头检查:

<?php

require_once __DIR__ . '/../../includes/functions.php';


// 检查插件是否启用

if (!isPluginEnabled('YourPlugin')) {

show404Page('该功能已禁用');

}

?>


6. 移动端适配

推荐做法: 使用 $isMobile 变量判断当前环境:

<?php

if ($isMobile) {

// 移动端代码

} else {

// PC端代码

}

?>


7. 安全性

- 不要信任用户输入: 所有输出使用 e() 函数转义

- SQL注入防护: 使用参数化查询 $db->query($sql, $params)

- XSS防护: 不要直接输出用户提交的内容


8. 性能优化

- 按需加载: 只在需要的钩子点执行代码

- 减少数据库查询: 缓存重复使用的数据

- CSS/JS优化: 避免加载不必要的资源


9. 调试技巧

- 查看错误日志: 检查 PHP 错误日志

- 使用 error_log: error_log('调试信息: ' . var_export($var, true));

- 浏览器开发者工具: 检查网络请求和控制台错误


10. 常见错误

| 错误信息 | 原因 | 解决方案 |

|---------------------------|----------------------|---------------------------------------|

| Cannot redeclare function | 函数重复定义 | 使用 function_exists() 包裹 |

| Undefined variable | 变量未定义 | 检查钩子点是否正确 |

| 404 Not Found | 路径错误 | 检查插件目录名和引用路径 |

| Access Denied | 直接访问 hook.php | 添加访问检查 |

| 插件不生效 | 未启用或钩子点错误 | 检查后台状态和钩子点名称 |


===========================================================================

完整示例:带函数定义的插件

===========================================================================

plugins/MyPlugin/hook.php:

<?php

/**

* 我的插件 - hook.php

*/


// 防止直接访问

if (!isset($hookPoint)) {

return;

}


// ============================================

// 函数定义(使用 function_exists 防止重复定义)

// ============================================


if (!function_exists('myPluginGetData')) {

/**

* 获取插件数据

*/

function myPluginGetData($userId) {

$db = Database::getInstance();

return $db->queryOne("SELECT * FROM my_plugin_data WHERE user_id = ?", [$userId]);

}

}


if (!function_exists('myPluginRenderWidget')) {

/**

* 渲染插件组件

*/

function myPluginRenderWidget($data) {

// ...

}

}


// ============================================

// 根据钩子点执行不同逻辑

// ============================================


switch ($hookPoint) {

case 'page_header':

// 加载CSS

?>

<link rel="stylesheet" href="<?php echo SITE_URL; ?>/plugins/MyPlugin/style.css">

<?php

break;

case 'page_footer':

// 显示浮动按钮

?>

<a href="<?php echo SITE_URL; ?>/plugins/MyPlugin/page.php" class="my-plugin-float-btn">

<i class="fas fa-star"></i>

</a>

<?php

break;

}

?>


===========================================================================

更新日志

===========================================================================

v1.2.0 (2026-02-16)

- 添加详细的注意事项说明

- 添加函数重复定义问题的解决方案

- 添加完整示例代码


v1.1.0 (2026-02-12)

- 添加多个钩子点(page_header, page_footer, user_profile_sidebar等)

- 添加丰富的系统变量支持

- 添加插件访问控制(禁用后自动404)

- 添加插件管理函数


v1.0.0

- 初始版本发布

- 支持基础钩子机制


===========================================================================

文档版本: 1.2

最后更新: 2026-02-16

===========================================================================