98实名认证系统 插件开发全套详细教程
2026-5-21 11:00 admin 65人
05-21 65人
本教程适配98实名认证系统自研 PHP 插件管理系统,基于PluginService插件服务类开发,统一代码规范、目录结构、数据库规则、权限验证、前后台页面写法,支持插件一键安装、一键卸载、自动生成后台菜单、用户菜单、分页搜索、AJAX 无刷新提交,零基础照着写就能开发商用插件。
二、插件目录结构(强制标准)
所有插件统一存放站点根目录 plugins 文件夹内
plugins/插件标识名/
├─ plugin.json 插件配置文件(必须)
├─ admin.php 管理员后台页面(必须)
├─ user.php 用户前台页面(可选)
├─ install.php 安装建表脚本(必须)
└─ uninstall.php 卸载删表脚本(必须)
插件命名规则
仅使用小写英文 + 数字 + 下划线
禁止中文、大写、特殊符号、空格
示例:site_setting、user_sign、balance_withdraw
三、插件配置文件 plugin.json
{
"name": "插件文件夹名称",
"title": "插件中文名称",
"description": "插件功能简介",
"version": "1.0.0",
"author": "开发者",
"status": 1
}
数说明
name:必须和插件文件夹名字完全一致,不一致系统识别未安装
title:插件后台展示名称、侧边菜单名称
description:插件功能介绍
version:插件版本号
author:插件作者
status:默认启用状态固定填 1
四、后台管理页面 admin.php 标准模板
1. 头部固定引入代码
<?php
declare(strict_types=1);
require_once BASE_PATH . '/core/Auth.php';
require_once BASE_PATH . '/core/Database.php';
Auth::requireAdmin();
$db = Database::getInstance();
$pageTitle = "后台页面标题";
头部代码作用
declare (strict_types=1):严格语法模式,适配高版本 PHP
BASE_PATH:系统全局根目录常量
Auth.php:权限验证类
Database.php:全局 PDO 数据库单例
Auth::requireAdmin ():仅管理员可访问,拦截普通用户
$db:全局数据库连接实例
$pageTitle:页面标题
AJAX 通用提交代码
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['act'])) {
$act = $_POST['act'];
@ob_clean();
header('Content-Type: application/json; charset=utf-8');
try {
//保存配置
if ($act === 'save_config') {
echo json_encode(['code' => 0, 'msg' => '保存成功']);
exit;
}
//单条删除
if ($act === 'del') {
echo json_encode(['code' => 0]);
exit;
}
//批量删除
if ($act === 'batch_del') {
echo json_encode(['code' => 0]);
exit;
}
} catch (Exception $e) {
echo json_encode(['code' => 1, 'msg' => $e->getMessage()]);
exit;
}
exit;
}
提交返回规则
成功:code=0 加提示文字
失败:code=1 加错误信息
3. 分页 + 搜索通用代码
$keyword = trim($_GET['keyword'] ?? '');
$page = max(1,(int)$_GET['page']);
$page_size = 15;
$offset = ($page - 1) * $page_size;
$where = "1=1";
$params = [];
if($keyword){
$where .= " AND username LIKE ?";
$params[] = "%$keyword%";
}
$totalStmt = $db->prepare("SELECT COUNT(*) FROM 数据表 WHERE ".$where);
$totalStmt->execute($params);
$total = $totalStmt->fetchColumn();
$listStmt = $db->prepare("SELECT * FROM 数据表 WHERE ".$where." ORDER BY id DESC LIMIT ".$offset.",".$page_size);
$listStmt->execute($params);
$list = $listStmt->fetchAll(PDO::FETCH_ASSOC);
页面输出与底部引入
<?php ob_start(); ?>
<!-- 此处填写layui表单、表格、搜索HTML代码 -->
<script>
layui.use(['jquery','layer','laypage','form'],function(){
var $ = layui.$;
var form = layui.form;
layui.laypage.render({
elem:'pager',
count:<?=$total?>,
limit:<?=$page_size?>,
curr:<?=$page?>,
jump:function(obj,first){
if(!first){
let kw = $('#keyword').val();
location.href='?route=admin/plugin/插件标识&page='+obj.curr+'&keyword='+encodeURIComponent(kw);
}
}
});
});
</script>
<?php
$content = ob_get_clean();
require BASE_PATH . '/admin/views/layout.php';
?>
五、用户前台页面 user.php 标准模板
1. 头部固定引入
<?php
declare(strict_types=1);
require_once BASE_PATH . '/core/Auth.php';
require_once BASE_PATH . '/core/Database.php';
Auth::requireLogin();
$db = Database::getInstance();
$pageTitle = "用户中心标题";
$uid = Auth::userId();
常用函数
Auth::requireLogin ():强制登录,未登录跳转登录页
Auth::userId ():获取当前登录用户 ID
2. 底部固定引入
<?php
$content = ob_get_clean();
require BASE_PATH . '/user/views/layout.php';
?>
六、插件安装脚本 install.php
<?php
declare(strict_types=1);
require_once BASE_PATH . '/core/Database.php';
$db = Database::getInstance();
try {
//创建配置表
$db->exec("CREATE TABLE IF NOT EXISTS plugin_demo_config (
id INT PRIMARY KEY AUTO_INCREMENT,
status TINYINT DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
//创建业务数据表
$db->exec("CREATE TABLE IF NOT EXISTS plugin_demo_log (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
create_time INT NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
//初始化默认数据
$init = $db->query("SELECT id FROM plugin_demo_config LIMIT 1");
if(!$init->fetchColumn()){
$db->exec("INSERT INTO plugin_demo_config(status) VALUES(1)");
}
//自动写入系统插件表
$pluginName = "demo";
$check = $db->prepare("SELECT id FROM plugins WHERE name=?");
$check->execute([$pluginName]);
if($check->fetchColumn()){
$db->prepare("UPDATE plugins SET status=1 WHERE name=?")->execute([$pluginName]);
}else{
$db->prepare("INSERT INTO plugins(name,title,version,status)VALUES(?,?,?,1)")->execute([$pluginName,"演示插件","1.0.0"]);
}
} catch (Exception $e) {
die(json_encode(['code'=>1,'msg'=>'安装失败']));
}
数据库规范
所有数据表前缀必须为 plugin_
配置表:plugin_标识_config
日志表:plugin_标识_log
统一编码 utf8mb4
时间字段统一使用 int 时间戳
七、插件卸载脚本 uninstall.php
<?php
declare(strict_types=1);
require_once BASE_PATH . '/core/Database.php';
$db = Database::getInstance();
try {
$db->exec("DROP TABLE IF EXISTS plugin_demo_config");
$db->exec("DROP TABLE IF EXISTS plugin_demo_log");
} catch (Exception $e) {
die(json_encode(['code'=>1,'msg'=>'卸载失败']));
}
八、系统常用内置函数大全
管理员登录验证:Auth::requireAdmin();
用户登录验证:Auth::requireLogin();
获取用户 ID:Auth::userId();
数据库实例:$db = Database::getInstance();
查询单条数据:$db->query("sql")->fetch(PDO::FETCH_ASSOC);
查询多条数据:$db->prepare("sql")->execute()->fetchAll(PDO::FETCH_ASSOC);
判断数据是否存在:$db->query("sql")->fetchColumn();
九、页面开发规范
全部使用原生 LayUI 组件开发
页面容器统一使用 layui-card
弹窗提示使用 layer.msg
确认弹窗使用 layer.confirm
分页固定使用 laypage
表格添加 overflow-x:auto 适配手机端左右滑动
表单统一使用 layui-form 样式
十、常见问题解决
插件显示未安装
解决:文件夹名称与 plugin.json 内 name 一致,重新卸载安装
后台页面无法访问
解决:缺少 Auth::requireAdmin() 权限代码
安装插件失败
解决:install.php 内无多余乱码、无混入 json 代码
AJAX 提交无响应
解决:添加 json 头部声明代码
菜单不自动生成
解决:必须走官方安装流程,禁止手动导入数据表
欢迎留言