madong / query
The Madong Query component - A powerful query parameter parsing and filtering library
1.0.1
2026-03-11 03:46 UTC
Requires
- php: >=8.1
- illuminate/database: ^11.0
- illuminate/pagination: ^11.0
- madong/helper: ^1.1
Suggests
- laravel/framework: For Laravel integration
README
一个强大的查询参数解析和过滤库,为 PHP 8.1+ 项目提供灵活、类型安全的查询构建能力。
✨ 特性
- 🚀 高性能: 轻量级设计,最小化性能开销
- 🔒 类型安全: 使用 PHP 8.1+ 枚举提供编译时类型检查
- 🎯 灵活配置: 支持多种查询模式和参数格式
- 🛠 易于集成: 提供多种集成方式(Trait、依赖注入、门面)
- 📝 优雅 API: 直观的接口设计,降低学习成本
- 🧪 完整测试: 全面的测试覆盖
- 📦 零依赖: 仅依赖 Illuminate 组件
- 🎛 高度可配置: SelectInput 支持字段过滤、格式限定、自定义返回格式等
📦 安装
通过 Composer 安装:
composer require madong/query
环境要求
- PHP >= 8.1
- illuminate/database >= 11.0
- illuminate/pagination >= 11.0
🚀 快速开始
基本使用
use madong\query\QueryParamsManager;
// 创建管理器实例
$manager = new QueryParamsManager();
// 应用查询参数
$query = $manager->apply(User::query(), [
'filters' => [
['field' => 'name', 'operator' => 'like', 'value' => 'John'],
['field' => 'age', 'operator' => 'gt', 'value' => 18]
],
'sort' => ['created_at' => 'desc'],
'limit' => 20
]);
// 获取结果
$users = $query->get();
使用 Trait(推荐)
在 Controller 中使用:
use madong\query\traits\WithQueryParams;
class UserController extends Controller
{
use WithQueryParams;
public function index(Request $request)
{
$params = $request->all();
return $this->paginateWithParams(User::query(), $params, [
'keyword_fields' => ['name', 'email']
]);
}
}
使用门面(CLI 环境)
use madong\query\QueryFacade;
$result = QueryFacade::paginate(User::class, $params);
📖 核心概念
查询参数格式
支持多种查询参数格式:
1. 标准 filters 格式
$params = [
'filters' => [
['field' => 'name', 'operator' => 'like', 'value' => 'John'],
['field' => 'status', 'operator' => 'eq', 'value' => 'active']
]
];
2. 大写前缀格式
$params = [
'LIKE_name' => 'John',
'EQ_status' => 'active'
];
3. 数组格式
$params = [
['name', 'like', 'John'],
['status', 'eq', 'active']
];
支持的操作符
| 操作符 | 说明 | 示例 |
|---|---|---|
eq | 等于 | ['field' => 'status', 'operator' => 'eq', 'value' => 'active'] |
ne | 不等于 | ['field' => 'status', 'operator' => 'ne', 'value' => 'deleted'] |
gt | 大于 | ['field' => 'age', 'operator' => 'gt', 'value' => 18] |
gte | 大于等于 | ['field' => 'age', 'operator' => 'gte', 'value' => 18] |
lt | 小于 | ['field' => 'age', 'operator' => 'lt', 'value' => 60] |
lte | 小于等于 | ['field' => 'age', 'operator' => 'lte', 'value' => 60] |
like | 模糊匹配 | ['field' => 'name', 'operator' => 'like', 'value' => 'John'] |
ilike | 不区分大小写模糊匹配 | ['field' => 'name', 'operator' => 'ilike', 'value' => 'john'] |
in | 包含 | ['field' => 'id', 'operator' => 'in', 'value' => [1, 2, 3]] |
not_in | 不包含 | ['field' => 'id', 'operator' => 'not_in', 'value' => [4, 5, 6]] |
between | 范围 | ['field' => 'price', 'operator' => 'between', 'value' => [10, 100]] |
not_between | 非范围 | ['field' => 'price', 'operator' => 'not_between', 'value' => [10, 100]] |
null | 为空 | ['field' => 'deleted_at', 'operator' => 'null'] |
not_null | 不为空 | ['field' => 'deleted_at', 'operator' => 'not_null'] |
枚举类型
Operator 枚举
use madong\query\enum\Operator;
$operator = Operator::LIKE;
echo $operator->value; // 输出: like
QueryMode 枚举
use madong\query\enum\QueryMode;
$mode = QueryMode::STANDARD; // 标准模式
$mode = QueryMode::STRICT; // 严格模式
ParamFormat 枚举
use madong\query\enum\ParamFormat;
$format = ParamFormat::FILTERS; // 标准 filters 格式
$format = ParamFormat::UPPERCASE; // 大写前缀格式
$format = ParamFormat::ARRAY; // 三元素数组格式
$format = ParamFormat::WHERE; // 直接 where 条件格式
$format = ParamFormat::AUTO; // 自动检测格式
🎯 高级用法
自定义查询选项
$manager->apply(User::query(), $params, [
'allowed_fields' => ['name', 'email', 'status'], // 允许查询的字段
'keyword_fields' => ['name', 'email'], // 关键词搜索字段
'default_sort' => ['created_at' => 'desc'], // 默认排序
'default_page' => 1, // 默认页码
'default_page_size' => 20, // 默认每页数量
'max_page_size' => 100 // 最大每页数量
]);
关键词搜索
$params = [
'keyword' => 'John',
'keyword_fields' => ['name', 'email', 'phone']
];
// 自动在指定字段中进行模糊搜索
$users = $manager->all(User::query(), $params, [
'keyword_fields' => ['name', 'email']
]);
分页查询
$result = $manager->paginate(User::query(), [
'filters' => [
['field' => 'status', 'operator' => 'eq', 'value' => 'active']
],
'page' => 1,
'page_size' => 20
], [
'keyword_fields' => ['name', 'email']
]);
// 返回格式
[
'data' => [...], // 数据列表
'total' => 100, // 总数
'page' => 1, // 当前页
'page_size' => 20, // 每页数量
'last_page' => 5 // 最后一页
]
排序
$params = [
'sort' => [
'created_at' => 'desc', // 降序
'name' => 'asc' // 升序
]
];
多层查询
$params = [
'filters' => [
['field' => 'status', 'operator' => 'eq', 'value' => 'active'],
['field' => 'age', 'operator' => 'gt', 'value' => 18],
['field' => 'name', 'operator' => 'like', 'value' => 'John']
]
];
🔧 集成方式
1. Controller 集成
use madong\query\traits\WithQueryParams;
class AdminController extends Controller
{
use WithQueryParams;
public function index(Request $request)
{
return $this->paginateWithParams(User::query(), $request->all(), [
'keyword_fields' => ['name', 'email']
]);
}
}
2. Service 集成
use madong\query\traits\WithServiceQuery;
class UserService extends BaseService
{
use WithServiceQuery;
public function getList(array $params): array
{
return $this->paginateWithParams(User::query(), $params, [
'allowed_fields' => ['name', 'email', 'status']
]);
}
}
3. DAO 集成
use madong\query\traits\WithDaoQuery;
class UserDao extends BaseDao
{
use WithDaoQuery;
public function search(array $params): Collection
{
return $this->allWithParams($this->getModel(), $params);
}
}
4. 依赖注入
use madong\query\QueryParamsManager;
class UserController extends Controller
{
public function __construct(
private QueryParamsManager $queryParams
) {}
public function index(Request $request)
{
return $this->queryParams->paginate(User::query(), $request->all());
}
}
5. SelectInput 集成(灵活参数解析)
WithSelectInput Trait 提供高度可配置的参数解析功能,适用于需要精确控制的场景。
基本使用
use madong\query\traits\WithSelectInput;
class UserController extends Controller
{
use WithSelectInput;
public function index(Request $request)
{
// 使用默认配置,返回标准格式
[$where, $format, $limit, $field, $order, $page] = $this->selectInput($request);
// 查询数据
$list = User::where($where)
->orderByRaw($order)
->paginate($limit, ['*'], 'page', $page);
return response()->json($list);
}
}
自定义配置
use madong\query\traits\WithSelectInput;
use madong\query\QuerySelectConfig;
class UserController extends Controller
{
use WithSelectInput;
public function index(Request $request)
{
// 创建自定义配置
$config = QuerySelectConfig::make([
'allowed_fields' => ['name', 'email', 'status', 'created_at'],
'skip_fields' => ['password', 'token', 'deleted_at'],
'keyword_fields' => ['name', 'email'],
'enable_keyword_search' => true,
'sort_fields' => ['name', 'email', 'created_at'],
'default_sort' => ['created_at' => 'desc'],
'default_page_size' => 20,
'max_page_size' => 100,
]);
// 使用自定义配置
$result = $this->selectInputWithConfig($request, $config);
$where = $result['where'];
$order = $result['order'];
// ...
}
}
配置选项
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
return_format | string | 'array' | 返回格式:array、object、compact |
param_format | string | 'auto' | 参数格式:filters、uppercase、array、where、auto |
allowed_fields | array\|null | null | 允许的字段白名单 |
skip_fields | array | [] | 跳过的字段黑名单 |
sort_fields | array\|null | null | 允许排序的字段 |
default_sort | array | [] | 默认排序规则 |
default_page_size | int | 10 | 默认每页数量 |
max_page_size | int | 100 | 最大每页数量 |
default_page | int | 1 | 默认页码 |
keyword_fields | array | [] | 关键词搜索字段 |
enable_keyword_search | bool | false | 是否启用关键词搜索 |
keyword_param | string | 'keyword' | 关键词参数名 |
enable_range_query | bool | true | 是否启用范围查询 |
enable_like_query | bool | true | 是否启用模糊匹配 |
auto_convert_datetime | bool | true | 是否自动转换日期时间 |
skip_empty_values | bool | true | 是否跳过空值 |
debug_mode | bool | false | 是否启用调试模式 |
在 Crud 中使用(推荐)
class UserController extends Crud
{
// 类属性配置
protected ?array $selectInputConfig = [
'allowed_fields' => ['name', 'email', 'status'],
'skip_fields' => ['password', 'token'],
'sort_fields' => ['name', 'created_at'],
'default_sort' => ['created_at' => 'desc'],
];
public function index(Request $request)
{
// 自动使用类属性配置
[$where, $format, $limit, $field, $order, $page] = $this->selectInput($request);
// ...
}
public function search(Request $request)
{
// 临时传入配置,不影响其他方法
[$where, $format, $limit, $field, $order, $page] = $this->selectInput($request, [
'keyword_fields' => ['name', 'email'],
'enable_keyword_search' => true,
]);
// ...
}
}
配置优先级:方法参数配置 > 类属性配置 > 默认配置
🛠️ 核心类
QueryParamsManager
查询参数管理器,提供统一的查询处理入口。
use madong\query\QueryParamsManager;
$manager = new QueryParamsManager();
// 应用查询参数
$query = $manager->apply($modelOrQuery, $params, $options);
// 解析查询参数
$parsed = $manager->parse($params);
// 分页查询
$result = $manager->paginate($modelOrQuery, $params, $options);
// 查询所有
$all = $manager->all($modelOrQuery, $params, $options);
// 查询第一条
$first = $manager->first($modelOrQuery, $params, $options);
QueryCondition
查询条件对象,封装单个查询条件。
use madong\query\QueryCondition;
$condition = new QueryCondition('name', 'like', 'John');
echo $condition->field; // name
echo $condition->operator; // like
echo $condition->value; // John
// 静态工厂方法
$condition = QueryCondition::eq('status', 'active');
$condition = QueryCondition::like('name', 'John');
$condition = QueryCondition::in('id', [1, 2, 3]);
QueryParamParser
查询参数解析器,支持多种参数格式。
use madong\query\QueryParamParser;
$parser = new QueryParamParser();
// 解析参数
$conditions = $parser->parse($params);
QueryBuilderHelper
查询构建器辅助类,应用查询条件到构建器。
use madong\query\QueryBuilderHelper;
$helper = new QueryBuilderHelper();
$query = $helper->apply($query, $params, $options);
QueryParamConverter
参数转换器,转换不同格式的参数。
use madong\query\QueryParamConverter;
$converter = new QueryParamConverter();
// 转换为标准格式
$standard = $converter->toStandard($params);
// 转换为数组格式
$array = $converter->toArray($params);
QueryFacade
门面类,提供静态访问接口(适用于 CLI 环境)。
use madong\query\QueryFacade;
$result = QueryFacade::paginate(User::class, $params);
🧪 异常处理
QueryException
基础查询异常。
use madong\query\exception\QueryException;
try {
// 查询操作
} catch (QueryException $e) {
// 处理异常
}
QueryParseException
查询参数解析异常。
use madong\query\exception\QueryParseException;
try {
$manager->apply(User::query(), $params);
} catch (QueryParseException $e) {
// 处理解析异常
}
📚 完整示例
用户管理接口
namespace App\Http\Controllers;
use madong\query\traits\WithQueryParams;
use App\Models\User;
class UserController extends Controller
{
use WithQueryParams;
public function index(Request $request)
{
$params = $request->all();
$options = [
'allowed_fields' => ['name', 'email', 'status', 'created_at'],
'keyword_fields' => ['name', 'email'],
'default_sort' => ['created_at' => 'desc'],
'default_page_size' => 20,
'max_page_size' => 100
];
return $this->paginateWithParams(User::query(), $params, $options);
}
public function show($id, Request $request)
{
$params = $request->all();
return $this->firstWithParams(User::query(), array_merge($params, [
'filters' => [['field' => 'id', 'operator' => 'eq', 'value' => $id]]
]));
}
}
高级查询示例
$params = [
'filters' => [
['field' => 'status', 'operator' => 'eq', 'value' => 'active'],
['field' => 'age', 'operator' => 'between', 'value' => [18, 60]],
['field' => 'name', 'operator' => 'like', 'value' => 'John'],
['field' => 'created_at', 'operator' => 'gte', 'value' => '2024-01-01']
],
'sort' => [
'created_at' => 'desc',
'name' => 'asc'
],
'page' => 1,
'page_size' => 20
];
$result = $manager->paginate(User::query(), $params);
关键词搜索示例
$params = [
'keyword' => 'John Doe',
'keyword_fields' => ['name', 'email', 'phone']
];
$users = $manager->all(User::query(), $params, [
'keyword_fields' => ['name', 'email', 'phone']
]);
🎨 最佳实践
1. 使用 Trait 简化代码
// 推荐
class UserController extends Controller
{
use WithQueryParams;
public function index(Request $request)
{
return $this->paginateWithParams(User::query(), $request->all());
}
}
// 不推荐
class UserController extends Controller
{
public function index(Request $request)
{
$manager = new QueryParamsManager();
return $manager->paginate(User::query(), $request->all());
}
}
2. 配置允许查询的字段
$options = [
'allowed_fields' => ['name', 'email', 'status'] // 只允许这些字段
];
3. 设置分页限制
$options = [
'default_page_size' => 20,
'max_page_size' => 100 // 防止查询过多数据
];
4. 使用关键词搜索
$options = [
'keyword_fields' => ['name', 'email'] // 指定搜索字段
];
🔒 安全建议
- 限制允许查询的字段: 使用
allowed_fields选项 - 设置分页上限: 使用
max_page_size选项 - 验证输入数据: 对用户输入进行验证
- 使用参数绑定: 底层自动使用参数绑定防止 SQL 注入
📄 许可证
Apache-2.0 License
👨💻 作者
Mr. April - 405784684@qq.com
🌐 官方网站
🤝 贡献
欢迎提交 Issue 和 Pull Request!
📞 支持
如有问题,请提交 Issue 或联系作者。