PHPackages                             teanxo/think-search - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Search &amp; Filtering](/categories/search)
4. /
5. teanxo/think-search

ActiveLibrary[Search &amp; Filtering](/categories/search)

teanxo/think-search
===================

00PHP

Since Apr 13Pushed 2y ago1 watchersCompare

[ Source](https://github.com/teanxo/ThinkSearch)[ Packagist](https://packagist.org/packages/teanxo/think-search)[ RSS](/packages/teanxo-think-search/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

基于ThinkPHP的ORM搜索器
-----------------

[](#基于thinkphp的orm搜索器)

### 为什么会有它？

[](#为什么会有它)

经常被一些搜索弄的代码可读性直线下降，例如公司之前维护的老系统代码的搜索是这样的

```
$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(复杂实例)

[](#输出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
)
```

### 注意事项

[](#注意事项)

1. 搜索器默认会过滤空字符串及空数组，若您觉得不满意可指定filter自定义规则函数
2. 若使用字符串格式，则保证分隔符需为英文逗号(,)

### AddMapping参数描述

[](#addmapping参数描述)

参数描述columnName需要处理的字段名称(通常用于请求参数中的名称)aliasName别名,如使用联表查询 则可设置该属性selectType字段匹配模式｜valueFormater自定义字段值处理函数(return: mixed)filter自定义规则函数(return: bool)nameFormatter自定义字段名称函数(return mixed)desc参数描述信息### 匹配模式

[](#匹配模式)

指定addMapping方法中的selectType参数将匹配不同的搜索器模式

参数描述sql参考SearchType::Equals默认值，比较模式where type = 1SearchType::Like模糊搜索模式where username like "%张三%"SearchType::Between区间搜索模式where age BETWEEN 18 AND 30SearchType::BetweenTime时间搜索模式(在区间搜索模式基础上加入补充时间后位数及时间戳格式化)SearchType::Inin查询where id in (1,2,3)｜SearchType::Innot in查询where id not in (1,2,3)｜

###  Health Score

12

—

LowBetter than 0% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity0

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity19

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/a7f84e20357e8438ee0c4a8c152d2d6f453203245aa27156bddcd3a3ca05ff47?d=identicon)[tanxiao123](/maintainers/tanxiao123)

---

Top Contributors

[![teanxo](https://avatars.githubusercontent.com/u/34929549?v=4)](https://github.com/teanxo "teanxo (8 commits)")

### Embed Badge

![Health badge](/badges/teanxo-think-search/health.svg)

```
[![Health](https://phpackages.com/badges/teanxo-think-search/health.svg)](https://phpackages.com/packages/teanxo-think-search)
```

###  Alternatives

[ruflin/elastica

Elasticsearch Client

2.3k50.4M203](/packages/ruflin-elastica)[opensearch-project/opensearch-php

PHP Client for OpenSearch

15024.3M65](/packages/opensearch-project-opensearch-php)[mailerlite/laravel-elasticsearch

An easy way to use the official PHP ElasticSearch client in your Laravel applications.

934529.3k2](/packages/mailerlite-laravel-elasticsearch)[massive/search-bundle

Massive Search Bundle

721.4M13](/packages/massive-search-bundle)[shyim/opensearch-php-dsl

OpenSearch/Elasticsearch DSL library

175.9M9](/packages/shyim-opensearch-php-dsl)[outl1ne/nova-multiselect-filter

Multiselect filter for Laravel Nova.

45802.7k3](/packages/outl1ne-nova-multiselect-filter)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
