flynn / field-mapper
HTTP请求字段转换工具,用于隐藏数据库真实字段名,支持Laravel和ThinkPHP框架
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/flynn/field-mapper
Requires
- php: >=7.4.0
Requires (Dev)
- phpunit/phpunit: ^8.0 || ^9.0
- topthink/framework: ^8.0
Suggests
- ext-redis: Required for Redis cache support
README
一个PHP Composer包,用于在HTTP传输数据时避免显示数据库真实字段名,提高API安全性。转换后的字段长度不大于6位,使用[a-z]字符集。支持Laravel和ThinkPHP框架。
功能特性
- 自动生成安全的字段映射,隐藏数据库真实字段名
- 支持正向映射(真实字段→安全字段)和反向映射(安全字段→真实字段)
- 支持数组和对象的递归映射
- 映射字段符合长度(≤6位)和字符集([a-z_-])要求
- 提供Laravel框架集成支持
- 支持ThinkPHP8框架集成
- 提供中间件自动处理请求和响应
- 支持映射关系的持久化存储和加载
- 支持文件缓存和Redis缓存
- 自动保存和加载映射关系
安装
使用Composer安装:
composer require flynn/field-mapper
基本使用
默认使用(文件缓存)
use Flynn\FieldMapper\FieldMapper; // 创建映射器实例(默认使用文件缓存) $fieldMapper = new FieldMapper(); // 映射单个字段 $mappedField = $fieldMapper->mapField('user_id'); // 返回类似 'abcde' 的3-6位小写字母 // 映射数组中的所有字段 $mappedData = $fieldMapper->mapArray([ 'user_id' => 1, 'username' => 'admin', 'email' => 'admin@example.com' ]); // 反向映射字段 $realField = $fieldMapper->reverseMapField('abcde'); // 返回 'user_id' // 反向映射数组 $realData = $fieldMapper->reverseMapArray([ 'abcde' => 1, 'fghij' => 'admin', 'klmno' => 'admin@example.com' ]); // 保存映射关系到缓存 $fieldMapper->saveToCache();
使用Redis缓存
use Flynn\FieldMapper\FieldMapper; // 创建Redis实例(注意使用完整命名空间) $redis = new \Redis(); $redis->connect('127.0.0.1', 6379); // 使用Redis缓存配置创建映射器实例 $fieldMapper = new FieldMapper([ 'cache_type' => 'redis', 'redis' => $redis, 'redis_key_prefix' => 'field_mapper:', 'redis_ttl' => 86400, // 24小时过期 'auto_load' => true, 'auto_save' => true ]);
Redis不可用时的异常处理
当选择Redis缓存类型但Redis不可用时,系统会直接抛出异常,而不是自动降级到文件缓存。建议在使用Redis缓存时添加适当的错误处理:
use Flynn\FieldMapper\FieldMapper; // 创建Redis实例 $redis = new \Redis(); $redis->connect('127.0.0.1', 6379); try { // 尝试使用Redis缓存 $fieldMapper = new FieldMapper([ 'cache_type' => 'redis', 'redis' => $redis ]); } catch (\Exception $e) { // Redis不可用时的处理逻辑 echo "Redis cache initialization failed: " . $e->getMessage(); // 可以在这里手动切换到文件缓存 $fieldMapper = new FieldMapper([ 'cache_type' => 'file', 'file_path' => './field-mapper.json' ]); } ## 配置选项 ```php $config = [ // 缓存类型:'file' 或 'redis' 'cache_type' => 'file', // 文件缓存配置 'file_path' => './field-mapper.json', // Redis缓存配置 'redis' => null, // Redis实例 'redis_key_prefix' => 'field_mapper:', 'redis_ttl' => 0, // 0表示永不过期 // 自动加载映射 'auto_load' => true, // 自动保存映射 'auto_save' => true ]; $fieldMapper = new FieldMapper($config);
缓存操作方法
// 从缓存加载映射关系(根据配置自动选择文件或Redis) $mapper->loadFromCache(); // 保存映射关系到缓存(根据配置自动选择文件或Redis) $mapper->saveToCache(); // 获取缓存实例 $cache = $mapper->getCache(); // 设置自定义缓存实例(需要实现CacheInterface接口) $mapper->setCache($customCache); // 获取缓存配置 $config = $mapper->getCacheConfig(); // 获取映射表 $mappings = $mapper->getMappings(); // 获取反向映射关系 $reverseMappings = $mapper->getReverseMappings(); // 清除所有映射关系 $mapper->clearMappings();
Laravel 集成
注册服务提供者
在 config/app.php 文件中的 providers 数组中添加:
Flynn\FieldMapper\FieldMapperServiceProvider::class,
发布配置
运行以下命令发布配置文件:
php artisan vendor:publish --provider="Flynn\FieldMapper\FieldMapperServiceProvider" --tag="config"
配置选项
在 config/field-mapper.php 中可以配置:
return [ /* |-------------------------------------------------------------------------- | 缓存类型 |-------------------------------------------------------------------------- | | 指定使用的缓存类型:'file' 或 'redis' | */ 'cache_type' => 'file', /* |-------------------------------------------------------------------------- | 文件缓存配置 |-------------------------------------------------------------------------- | | 当cache_type为'file'时使用 | 在Laravel环境中,默认使用storage_path | */ 'file_path' => storage_path('field-mapper.json'), /* |-------------------------------------------------------------------------- | Redis缓存配置 |-------------------------------------------------------------------------- | | 当cache_type为'redis'时使用 | */ 'redis' => [ 'host' => '127.0.0.1', 'port' => 6379, 'password' => '', 'database' => 0, 'key_prefix' => 'field_mapper:', 'ttl' => 0, // 0表示永不过期 ], /* |-------------------------------------------------------------------------- | 自动加载映射 |-------------------------------------------------------------------------- | | 是否在初始化时自动加载映射关系 | */ 'auto_load' => true, /* |-------------------------------------------------------------------------- | 自动保存映射 |-------------------------------------------------------------------------- | | 是否在应用关闭时自动保存映射关系 | */ 'auto_save' => true ];
使用依赖注入
use Flynn\FieldMapper\FieldMapper; class ApiController extends Controller { protected $mapper; public function __construct(FieldMapper $mapper) { $this->mapper = $mapper; } public function index() { $users = User::all()->toArray(); return response()->json($this->mapper->mapArray($users)); } public function store(Request $request) { // 将请求中的安全字段名转换回真实字段名 $validatedData = $this->mapper->reverseMapArray($request->all()); // 处理数据... } }
使用 Facade
可以在配置文件中添加 Facade 别名,或者直接使用服务容器:
// 使用服务容器 $mapper = app('field-mapper'); // 或者使用 app() 辅助函数 $mapper = app(FieldMapper::class);
ThinkPHP8框架集成
注册服务
在 config/service.php 或 app/provider.php 中注册服务:
return [ 'services' => [ '\Flynn\FieldMapper\ThinkPHP\FieldMapperService', ], ];
配置文件
ThinkPHP的配置会自动从包中加载。你也可以复制配置文件到项目中自定义:
// 复制到项目后,配置会自动加载 // config/field_mapper.php return [ /* |-------------------------------------------------------------------------- | 缓存类型 |-------------------------------------------------------------------------- | | 指定使用的缓存类型:'file' 或 'redis' | */ 'cache_type' => 'file', /* |-------------------------------------------------------------------------- | 文件缓存配置 |-------------------------------------------------------------------------- | | 当cache_type为'file'时使用 | 在ThinkPHP环境中,默认使用runtime目录 | */ 'file_path' => App::getRuntimePath() . 'field-mapper.json', /* |-------------------------------------------------------------------------- | Redis缓存配置 |-------------------------------------------------------------------------- | | 当cache_type为'redis'时使用 | */ 'redis' => [ 'host' => '127.0.0.1', 'port' => 6379, 'password' => '', 'database' => 0, 'key_prefix' => 'field_mapper:', 'ttl' => 0, // 0表示永不过期 ], /* |-------------------------------------------------------------------------- | 自动加载映射 |-------------------------------------------------------------------------- | | 是否在初始化时自动加载映射关系 | */ 'auto_load' => true, /* |-------------------------------------------------------------------------- | 自动保存映射 |-------------------------------------------------------------------------- | | 是否在应用关闭时自动保存映射关系 | */ 'auto_save' => true, // 映射字段最大长度 'max_length' => 6, ];
使用中间件(推荐)
在 app/middleware.php 中添加中间件,自动处理请求和响应:
return [ '\Flynn\FieldMapper\ThinkPHP\middleware\FieldMapperMiddleware', ];
控制器中使用
namespace app\controller; use app\BaseController; use think\facade\Db; use think\facade\App; class UserController extends BaseController { public function index() { // 方法1: 使用服务容器获取实例 $mapper = App::get('field-mapper'); // 查询用户数据 $users = Db::name('users') ->field(['id', 'username', 'email']) ->select(); // 映射字段名 $mappedUsers = $mapper->processResultSet($users); return json([ 'code' => 200, 'data' => $mappedUsers ]); } // 方法2: 使用中间件后无需手动处理 public function store() { // 请求数据已被中间件自动反向映射 $data = $this->request->param(); // 直接使用转换后的数据(已映射为真实字段名) Db::name('users')->insert($data); // 响应也会被中间件自动正向映射 return json(['message' => 'success']); } }
ThinkPHP特殊处理
// 处理查询结果集的便捷方法 $mapper = App::get('field-mapper'); // 处理单条记录 $user = Db::name('users')->find(1); $mappedUser = $mapper->processResultSet($user); // 处理多条记录 $users = Db::name('users')->select(); $mappedUsers = $mapper->processResultSet($users); // 支持对象和数组混合的情况
安全说明
- 本包可以帮助隐藏数据库字段名,但并不能替代其他安全措施
- 对于敏感数据,建议同时使用加密和本包的字段映射功能
- 定期备份映射关系文件,避免映射关系丢失
- 考虑使用环境变量或其他安全方式配置映射文件路径
- 支持自动保存映射关系,确保映射一致性
- 确保在生产环境中配置适当的缓存TTL,避免映射关系永久存储
- 当使用Redis缓存时,确保Redis服务器配置了适当的访问控制
测试
运行测试:
composer test
许可证
本项目采用 MIT 许可证 - 详情请查看 LICENSE 文件