teanxo / think-search
There is no license information available for the latest version (dev-main) of this package.
dev-main
2024-04-13 06:07 UTC
Requires
- php: >=7.4
Requires (Dev)
- phpunit/phpunit: ^11
This package is auto-updated.
Last update: 2025-03-13 08:05:58 UTC
README
为什么会有它?
经常被一些搜索弄的代码可读性直线下降,例如公司之前维护的老系统代码的搜索是这样的
$username = $request->get("username"); if (!isset($keyword)){ $where[] = ['u.username', 'like', "%{$keyword}%"]; } $create_time = $request->get("create_time"); if (!isset($create_time)){ $times = explode($create_time) $where[] = ['u.create_time', 'between', $times[0], $times[1]]; } ...此处省略其它代码
抛开之前同事写的代码严谨性问题,光阅读性就已经开始让人头疼了
当然ThinkPHP也实现了搜索器查询,但当联表JOIN查询时,把搜索器方法写在不属于自己的模型类中时,属实是让我这个代码洁癖难以接受
于是趁业务时间封装出了一套搜索器
示例
// 假设这是前端请求时传入的查询参数 $requestParams = [ "username" => "1111", "create_time" => "2024-01-01,2024-03-01" ]; $searchWhere = ThinkSearch::getInstance($requestParams) ->addMapping(columnName:"username", selectType: SearchType::Like, desc: "用户名") ->addMapping(columnName:"create_time", selectType: SearchType::BetweenTime, desc: "创建时间") ->build(); // 您得到了一个可用于ORM查询的数组 Db::table("you_table")->where($searchWhere);
输出SQL(复杂实例)
$requestParams = [ "type" => "1", "keyword" => "13277777777", "create_time" => "2024-01-01,2024-03-01", "level" => "1" ]; $searchSql = ThinkSearch::getInstance($requestParams) ->addMapping( columnName: "type", nameFormatter: fn ($val) => match((int)$val){ 1 => "a.email", 2 => "a.phone" }, desc: "注册类型" ) ->addMapping(columnName: "keyword", aliasName: "u.username|u.phone|u.account", selectType: SearchType::Like,desc: "关键信息") ->addMapping(columnName: "create_time", aliasName: "u.create_time", selectType: SearchType::BetweenTime, desc: "用户创建时间") ->addMapping( columnName: "level", aliasName: "u.level", valueFormater: fn ($val) => match((int)$val){ 1 => [1,2,3], 2 => [4,5,6] }, desc: "身份类型", selectType: SearchType::In ) ->buildSql(isAutoWhere: true); // 结果输出 WHERE a.email = '1' AND ( u.username LIKE '13277777777' OR u.phone LIKE '13277777777' OR u.account LIKE '13277777777' ) AND u.create_time BETWEEN 1704067200 AND 1709337599 AND u.level IN (1,2,3)
时间查询
当使用SearchType::BetweenTime时,支持以下格式
[ // Date 字符串格式 "create_time" => "2024-01-01,2024,03-01", // DateTime 字符串格式 "create_time" => "2024-01-01 00:00:00,2024-03-01 23:59:59", // Date Array "create_time" => [ '2024-01-01', '2024,03-01' ], // DateTime Array "create_time" => [ '2024-01-01 00:00:00', '2024-03-01 23:59:59' ], ];
自定义字段值处理
$requestParams = [ "level" => "1", ]; $searchWhere = ThinkSearch::getInstance($requestParams) ->addMapping( columnName: "level", aliasName: "c.level", valueFormater: fn ($val) => match((int)$val){ 1 => [1,2,3], 2 => [4,5,6] }, selectType: SearchType::In ) ->build(); var_dump($searchWhere); // 结果输出 array(1) { [0]=> array(3) { [0]=> string(7) "c.level" [1]=> string(2) "in" [2]=> array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } } }
自定义字段名称处理
$requestParams = [ "type" => "1", ]; $searchWhere = ThinkSearch::getInstance($requestParams) ->addMapping( columnName: "type", nameFormatter: fn ($val) => match((int)$val){ 1 => "a.email", 2 => "a.phone" }, ) ->build(); var_dump($searchWhere); // 结果输出 Array ( [a.email] => 1 )
注意事项
- 搜索器默认会过滤空字符串及空数组,若您觉得不满意可指定filter自定义规则函数
- 若使用字符串格式,则保证分隔符需为英文逗号(,)
AddMapping参数描述
参数 | 描述 |
---|---|
columnName | 需要处理的字段名称(通常用于请求参数中的名称) |
aliasName | 别名,如使用联表查询 则可设置该属性 |
selectType | 字段匹配模式| |
valueFormater | 自定义字段值处理函数(return: mixed) |
filter | 自定义规则函数(return: bool) |
nameFormatter | 自定义字段名称函数(return mixed) |
desc | 参数描述信息 |
匹配模式
指定addMapping方法中的selectType参数将匹配不同的搜索器模式
参数 | 描述 | sql参考 |
---|---|---|
SearchType::Equals | 默认值,比较模式 | where type = 1 |
SearchType::Like | 模糊搜索模式 | where username like "%张三%" |
SearchType::Between | 区间搜索模式 | where age BETWEEN 18 AND 30 |
SearchType::BetweenTime | 时间搜索模式(在区间搜索模式基础上加入补充时间后位数及时间戳格式化) | |
SearchType::In | in查询 | where id in (1,2,3)| |
SearchType::In | not in查询 | where id not in (1,2,3)| |