wiseadmin / wise-dict
WiseAdmin 键值配置与字典管理包 — 支持多类型值、分组缓存、历史版本追溯与 HTML 净化过滤
No longer found in upstream repository
Requires
- php: >=8.1
- topthink/framework: ^6.0 || ^8.0
Suggests
- ezyang/htmlpurifier: Recommended for robust HTML XSS filtering
This package is auto-updated.
Last update: 2026-06-26 06:24:10 UTC
README
ThinkPHP 6/8 键值对配置管理扩展包,提供配置存储、缓存管理、历史版本追踪、字典管理、多命名空间隔离、继承链解析、标签分类和后台管理界面
✨ 特性
核心配置管理
- 多类型支持:文本(text)、数字(number)、富文本(html)、图片(image)、JSON(json)
- 多命名空间隔离:支持按 namespace 隔离配置,自动从请求上下文推断或显式指定
- 冒号路径解析:支持
namespace:group:key、group:key、key三种路径格式 - 配置分组:支持任意分组(如 system、mail、upload)
- 缓存自动刷新:配置变更时自动清除相关缓存,支持空值防缓存穿透
- 历史版本:完整记录每次配置变更,支持对比(diff)和回滚(revert)
- 批量操作:支持
setMany()批量设置、all()获取全部配置
字典管理(DictSDK)
- 字典类型管理:定义字典编码、名称、描述,支持树形字典标记
- 字典项 CRUD:完整的增删改查、分页列表、批量操作
- 树形字典:支持父子层级结构,兼容 Tree 工具库
- 便捷查询:value→label 映射、按值取标签
- 专用缓存:字典数据独立缓存,变更自动清理
- 自动安装:支持服务启动时自动创建数据表
高级特性
- 继承链(Inheritance):按 namespace 层级(如
project_a.plugin_mail.prod)向上查找配置,支持inherit=false阻断 - 标签管理(Tag):为配置附加标签,支持按标签 AND/OR 逻辑查询
- TP Config 桥接:将动态配置注入到
think\Config体系,使config('wise.system.xxx')可直接访问 - 类型扩展:通过实现
TypeHandlerInterface接口注册自定义类型处理器 - 事件驱动:保存前后、回滚、字典变更、标签变更时触发事件,便于其他模块监听
- 权限预留:支持通过闭包配置管理权限
- HTML XSS 过滤:内置基础过滤,建议搭配
ezyang/htmlpurifier获得更强防护 - 符合 ThinkPHP 约定:自动服务发现、门面模式、命令行工具
📦 安装
composer require wiseadmin/wise-config
推荐包
# 增强 HTML XSS 过滤
composer require ezyang/htmlpurifier
初始化
php think wise:config:publish
使用
--force参数可强制覆盖已有配置文件。
执行数据库迁移
php think migrate:run
将创建
config、config_history、config_tag、dict_type、dict_item五张数据表。
🚀 快速开始
ConfigManager(核心配置管理)
基础读写
使用 WiseConfig 门面:
use wise\config\facade\WiseConfig; // 读取配置 $siteName = WiseConfig::get('site_name', '默认名称'); // 设置配置 WiseConfig::set('site_name', '我的网站', [ 'type' => 'text', 'group' => 'system', 'title' => '站点名称', ]); // 批量获取 $configs = WiseConfig::many(['site_name', 'site_desc', 'admin_email']); // 获取分组所有配置 $mailConfigs = WiseConfig::getGroup('mail'); // 检查键是否存在 if (WiseConfig::has('site_name')) { // ... } // 删除配置 WiseConfig::delete('old_config_key'); // 批量设置 WiseConfig::setMany([ 'site_name' => ['value' => '新站点', 'type' => 'text', 'group' => 'system'], 'max_upload' => ['value' => '10', 'type' => 'number', 'group' => 'upload'], ]); // 获取当前 namespace 全部配置 $allConfigs = WiseConfig::all();
命名空间与路径
支持冒号分隔的三段路径 namespace:group:key,以及链式调用指定 namespace:
use wise\config\facade\WiseConfig; // 方式一:链式指定 namespace $value = WiseConfig::namespace('project_a')->get('site_name'); // 方式二:路径中指定 namespace $value = WiseConfig::get('project_a:system:site_name'); // namespace:group:key — 三段完整路径 // group:key — namespace 自动推断,默认值为 'default' // key — namespace 自动推断,group 默认为 'system'
继承链
支持多层级 namespace 的点分命名(如 project_a.plugin_mail.prod),子级可继承父级的配置:
// 获取最终生效值(自动沿继承链向上查找) $seoTitle = WiseConfig::namespace('project_a.plugin_mail') ->getResolved('seo:title', '默认标题'); // 链解析路径:project_a.plugin_mail → project_a → default // 查看配置来源 $status = WiseConfig::namespace('project_a.plugin_mail') ->getOverrideStatus('seo:title'); // 返回:['exists' => true, 'value' => '...', 'source_ns' => 'project_a', 'is_inherited' => true] // 删除当前 namespace 的覆盖值,恢复继承上级 WiseConfig::namespace('project_a.plugin_mail')->reset('seo:title');
设置配置时,通过
'inherit' => 0可阻断继承,上级同名配置不会生效。
标签管理
// 为配置添加标签 WiseConfig::addTag('site_name', 'seo'); // 移除标签 WiseConfig::removeTag('site_name', 'seo'); // 按标签查询配置(AND 逻辑) $seoConfigs = WiseConfig::whereTags(['seo', 'meta'], 'and'); // 按标签查询配置(OR 逻辑) $relatedConfigs = WiseConfig::whereTags(['seo', 'meta'], 'or');
TP Config 桥接
将动态配置注入到 ThinkPHP 原生 config() 函数体系:
use wise\config\bridge\TpConfigBridge; $bridge = app('wise.config.tp_config_bridge'); $bridge->injectToConfig('default', 'wise'); // 之后可通过 ThinkPHP 方式访问 echo config('wise.system.site_name'); // 站点名称 echo config('wise.upload.max_size'); // 上传限制
历史版本
// 获取历史版本列表 $histories = WiseConfig::getHistory('site_name'); // 获取指定历史记录 $history = WiseConfig::getHistoryById(1); // 回滚到指定版本 WiseConfig::revert($historyId); // 对比两个版本差异 $diff = WiseConfig::diff($historyIdA, $historyIdB); // 返回:['old' => ..., 'new' => ..., 'diff' => ..., 'is_json' => bool]
缓存管理
// 清除指定键缓存 WiseConfig::clearCacheForKey('site_name'); // 清除分组缓存 WiseConfig::clearCacheForGroup('system'); // 清除全部缓存 WiseConfig::clearAllCache();
DictSDK(字典管理)
DictSDK 提供静态方法调用,无需实例化:
use wise\config\DictSDK; // 获取字典项列表(启用状态) $items = DictSDK::getItems('order_status'); // 返回:[['item_value' => '1', 'item_label' => '待支付', ...], ...] // 获取 value => label 映射 $map = DictSDK::getValueLabelMap('order_status'); // 返回:['1' => '待支付', '2' => '已支付', ...] // 根据值获取标签 $label = DictSDK::getLabel('order_status', '1'); // 返回:'待支付' // 获取树形字典 $tree = DictSDK::getTree('region'); // 清除缓存 DictSDK::clearCache('order_status'); DictSDK::clearAllCache();
字典项 CRUD(服务层)
use wise\config\service\DictItemService; $service = app(DictItemService::class); // 创建字典项 $item = $service->createItem([ 'dict_code' => 'order_status', 'item_value' => '4', 'item_label' => '已完成', 'sort' => 4, ]); // 更新字典项 $service->updateItem(1, ['item_label' => '更新后标签']); // 分页查询 $list = $service->getList('order_status', [ 'page' => 1, 'limit' => 15, ]); // 批量操作 $service->batchUpdateStatus([1, 2, 3], 1); // 批量启用 $service->batchDelete([1, 2]); // 批量删除 // 删除字典项 $service->deleteItem(1);
支持的数据类型
| 类型标识 | 说明 | 存储格式 | 读取行为 |
|---|---|---|---|
text |
单行文本 | 字符串 | 原样返回 |
number |
数字 | 字符串 | 自动转为 int/float |
html |
富文本 | HTML 字符串 | 返回 HTML(安全过滤后) |
image |
单图 | 相对路径 | 自动拼接完整 URL |
json |
JSON 对象/数组 | JSON 字符串 | 自动解析为数组 |
类型扩展
实现 wise\config\contract\TypeHandlerInterface 接口即可扩展自定义类型:
use wise\config\contract\TypeHandlerInterface; class ColorHandler implements TypeHandlerInterface { public function getType(): string { return 'color'; } public function decode($rawValue) { return '#' . $rawValue; } public function encode($inputValue): string { return ltrim($inputValue, '#'); } public function renderFormField(string $name, $value, array $config): string { return '<input type="color" name="' . $name . '" value="' . $value . '">'; } } // 注册 $manager = app(\wise\config\ConfigManager::class); $manager->registerTypeHandler(new ColorHandler());
事件
配置事件
| 事件类 | 触发时机 | 关键参数 |
|---|---|---|
ConfigSaving |
配置保存前 | key, value, type, group, namespace |
ConfigSaved |
配置保存后 | key, oldValue, newValue, type, group, namespace |
ConfigDeleting |
配置删除前 | key, configId, group, namespace |
ConfigReverted |
配置回滚后 | key, fromValue, toValue, historyId, namespace |
字典事件
| 事件类 | 触发时机 | 关键参数 |
|---|---|---|
DictChangedEvent |
字典项增删改时 | dictCode, action(create/update/delete), data |
其他事件
| 事件类 | 触发时机 | 说明 |
|---|---|---|
TagChanged |
标签关联变更时 | 配置标签增删改 |
InheritanceBlocked |
继承被阻断时 | inherit=false 阻断上级继承 |
监听示例
// app/event.php use wise\config\event\ConfigSaved; use wise\config\event\DictChangedEvent; return [ 'listen' => [ ConfigSaved::class => [ \app\listener\ConfigChangeListener::class, ], DictChangedEvent::class => [ \app\listener\DictChangeListener::class, ], ], ];
⚙️ 配置
发布配置文件:
php think wise:config:publish
配置文件 config/wise-config.php:
return [ // ========== 表名配置 ========== 'table_names' => [ 'config' => 'config', 'config_history' => 'config_history', 'config_tag' => 'config_tag', 'dict_type' => 'dict_type', 'dict_item' => 'dict_item', ], // 缓存键前缀 'cache_key_prefix' => 'wise_config:', // 后台路由前缀 'route_prefix' => 'wise-admin/config', // 图片上传磁盘 'upload_disk' => 'public', // 图片上传路径前缀 'upload_path' => 'uploads/config/', // 缓存标签 'cache_tag' => 'wise_config', // 缓存有效期(秒),0 表示永久 'cache_ttl' => 0, // 空值缓存 TTL(秒),防穿透 'cache_null_ttl' => 3600, // 权限验证回调,返回 bool 'auth_callback' => null, // HTML XSS 过滤 'html_filter' => true, // 图片上传扩展名限制 'image_extensions' => 'jpg,jpeg,png,gif,webp,bmp', // 图片上传最大大小(KB) 'image_max_size' => 2048, // ========== 字典模块 ========== 'dict' => [ 'cache_ttl' => 86400, 'auto_install' => true, ], // ========== 命名空间 ========== 'namespace' => [ 'default' => 'default', 'auto_resolve' => true, ], // ========== 继承 ========== 'inheritance' => [ 'enabled' => true, 'max_depth' => 5, 'cache_ttl' => 300, ], // ========== 标签 ========== 'tag' => [ 'enabled' => true, 'max_per_config' => 10, ], // ========== TP Config 整合 ========== 'tp_integration' => [ 'inject_prefix' => 'wise', ], ];
权限配置示例
// 在 config/wise-config.php 中配置 'auth_callback' => function () { return \app\admin\facade\CurrentAdmin::isLogin(); },
📂 目录结构
src/
├── Service.php # 服务提供者
├── ConfigManager.php # 核心配置管理器
├── DictSDK.php # 字典静态门面 SDK
├── bridge/
│ └── TpConfigBridge.php # ThinkPHP Config 桥接器
├── cache/
│ └── DictCacheManager.php # 字典缓存管理器
├── command/
│ └── Publish.php # 发布命令
├── contract/
│ └── TypeHandlerInterface.php # 类型处理器接口
├── event/
│ ├── ConfigSaving.php # 配置保存前事件
│ ├── ConfigSaved.php # 配置保存后事件
│ ├── ConfigDeleting.php # 配置删除前事件
│ ├── ConfigReverted.php # 配置回滚事件
│ ├── DictChangedEvent.php # 字典变更事件
│ ├── InheritanceBlocked.php # 继承阻断事件
│ └── TagChanged.php # 标签变更事件
├── exception/
│ └── DictException.php # 字典异常类
├── facade/
│ └── WiseConfig.php # WiseConfig 静态门面
├── installer/
│ └── DictInstaller.php # 字典表安装器
├── manager/
│ └── TagManager.php # 标签管理器
├── middleware/
│ └── ConfigAuth.php # 权限中间件
├── model/
│ ├── ConfigModel.php # 配置模型
│ ├── ConfigHistoryModel.php # 历史模型
│ ├── ConfigTagModel.php # 标签关联模型
│ ├── DictItem.php # 字典项模型
│ └── DictType.php # 字典类型模型
├── resolver/
│ ├── PathResolver.php # 冒号路径三段解析器
│ ├── NamespaceResolver.php # 命名空间三级推断器
│ └── InheritanceResolver.php # 继承链解析器
├── service/
│ ├── DictItemService.php # 字典项 CRUD 服务
│ └── DictTypeService.php # 字典类型 CRUD 服务
└── trait/
├── CommandTrait.php # 命令发布共用 Trait
└── ServiceTrait.php # 服务提供者共用 Trait
📄 License
MIT