railken / search-query
Requires
- php: >=7.1
- railken/bag: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.16
- phpunit/phpunit: *
README
将简单的表达式(例如 'x eq 1 or y gt 2')转换为树对象。这在构建搜索的API端点时非常有用。
要求
PHP 7.1 或更高版本。
Composer
您可以通过以下命令使用Composer安装它:Composer
composer require railken/search-query
演示
用法
简单用法如下
use Railken\SQ\QueryParser; use Railken\SQ\Resolvers as Resolvers; $parser = new QueryParser(); $parser->addResolvers([ new Resolvers\ValueResolver(), new Resolvers\KeyResolver(), new Resolvers\GroupingResolver(), new Resolvers\NotEqResolver(), new Resolvers\EqResolver(), new Resolvers\LteResolver(), new Resolvers\LtResolver(), new Resolvers\GteResolver(), new Resolvers\GtResolver(), new Resolvers\CtResolver(), new Resolvers\SwResolver(), new Resolvers\NotInResolver(), new Resolvers\InResolver(), new Resolvers\EwResolver(), new Resolvers\NotNullResolver(), new Resolvers\NullResolver(), new Resolvers\AndResolver(), new Resolvers\OrResolver(), new Resolvers\TextResolver(), ]); $result = $query->parse('x eq 1 or y > 1');
$result
的 json 格式结果
{ "type": "Railken\\SQ\\Nodes\\OrNode", "value": "OR", "childs": [ { "type": "Railken\\SQ\\Nodes\\EqNode", "value": "EQ", "childs": [ { "type": "Railken\\SQ\\Nodes\\KeyNode", "value": "x" }, { "type": "Railken\\SQ\\Nodes\\ValueNode", "value": "1" } ] }, { "type": "Railken\\SQ\\Nodes\\GtNode", "value": "GT", "childs": [ { "type": "Railken\\SQ\\Nodes\\KeyNode", "value": "y" }, { "type": "Railken\\SQ\\Nodes\\ValueNode", "value": "1" } ] } ] }
节点
键节点
所有字母数字(以字母字符开头)都被转换为 KeyNode
。允许的其它字符: _
示例
created_at
值节点
所有数字和字符串都被转换为 ValueNode
。字符串的分隔符可以是 '
或 "
示例
"An apple"
30.20
分组节点
所有圆括号创建一个分组节点 ( ... )
。当然也可以嵌套分组。如果缺少括号,将抛出异常。
示例
(x or y) and z
((x > 10 and w) or (y > 5 and f)) and z
AND, OR
这些运算符需要在运算符前后有 Node
,否则将抛出异常。
可以是文字(and, or)或符号(&&, ||)
重要:如果定义了父分组并且 LogicNode 是唯一的子节点,LogicNode 将取代 GroupNode。
示例
x or y || z
x and y && z
EQ, NOT_EQ, GT, GTE, LT, LTE
所有这些运算符需要在运算符前后有 KeyNode
或 ValueNode
。可以是文字(eq, not eq, gt, gte, lt, lte)或符号(=, !=, >, >=, < <=)
示例
x eq 1
x = 1
x gt 1
x > 1
x gte 1
x >= 1
x lt 1
x < 1
x lte 1
x <= 1
也可以比较两个键
示例
x eq y
CT, SW, EW
这些运算符将处理字符串的比较:包含、以...开头和以...结尾。
示例
description ct "a random phrase"
description sw "the text must start with this"
description ew "the text must end with this"
NULL, NOT NULL
这些运算符不需要在运算符后有节点。
deleted_at is null
deleted_at is not null
自定义解析器
如您所见,为了解析查询,您必须添加解析器。因此,您可以自由添加任何您想要的解析器,但请注意顺序:KeyValue 和 NodeValue 是所有解析器的基础,所以请小心。
以下是一个自定义解析器和节点的示例
CustomResolver.php
<?php namespace App\SQ\Resolvers; use Railken\SQ\Resolvers\ComparisonOperatorResolver; use App\SQ\Nodes\CustomNode; class CustomResolver extends ComparisonOperatorResolver { /** * Node resolved * * @var string */ public $node = CustomNode::class; /** * Regex token * * @var string */ public $regex = [ '/(?<![^\s])custom(?![^\s])/i', ]; }
CustomNode.php
<?php namespace App\SQ\Nodes; use Railken\SQ\Nodes\ComparisonOperatorNode; class CustomNode extends ComparisonOperatorNode { /** * Value * * @var string */ public $value = 'CUSTOM'; }
记得在创建解析器的实例时添加解析器。
<?php $parser->addResolvers([ new \App\SQ\Resolvers\CustomResolver(), });
如果您有一个更复杂的节点要解析,只需将 resolve 方法添加到 CustomResolver。
<?php namespace App\SQ\Resolvers; use Railken\SQ\Contracts\ResolverContract; use Railken\SQ\Contracts\NodeContract; class CustomResolver implements ResolverContract { /** * Resolve node * * @param NodeContract $node * * @return NodeContract */ public function resolve(NodeContract $node) { return $node; } }
Railken\SQ\Languages\BoomTree\Resolvers\CustomResolver
还有一个 CustomResolver,它与所有子节点一起工作,并且可以通过闭包进行配置,它是 Railken\SQ\Languages\BoomTree\Resolvers\CustomResolver
。例如,您可以通过这样做为所有 KeyNode 添加前缀
use Railken\SQ\Languages\BoomTree\Resolvers; use Railken\SQ\Languages\BoomTree\Nodes; $parser->addResolvers([ new Resolvers\CustomResolver(function ($node) { if($node instanceof Nodes\KeyNode) { $node->setValue("myCustomPrefix.".$node->getValue()); } }), ]);
许可
开源软件,许可协议为 MIT 许可证。