globyapp / odata-query-parser
解析 OData v4 查询字符串,输出合适的 PHP 对象。
v1.1.0
2024-09-07 17:29 UTC
Requires
- php: >=8.2
- ext-mbstring: *
Requires (Dev)
- ext-simplexml: *
- friendsofphp/php-cs-fixer: ^3.16
- infection/infection: ^0.27.11
- phpstan/phpstan: ^1.10
- phpstan/phpstan-deprecation-rules: ^1.1
- phpunit/phpunit: 10.*
- vimeo/psalm: ^5.23
This package is auto-updated.
Last update: 2024-09-07 17:30:25 UTC
README
解析 OData v4 查询字符串,输出合适的 PHP 对象。
摘要
关于
我只需要解析查询字符串,将 OData v4 命令转换为可理解的数组,以便我可以用它来制作一个 Laravel 扩展包,以便自动使用 Eloquent 根据解析的 OData v4 命令数组来过滤响应。
因为我没有看到专门处理解析查询字符串的包,并且看到 有些人自己做了但没有开源,所以我决定自己开始一个。
功能
- 解析 URL 并返回数组
- 支持
$select
、$top
、$skip
、$orderby
、$count
- 对
$filter
的部分支持(请参阅已知问题部分) - 您可以使用一种解析模式,让您解析这些关键字而不需要在其前面添加
$
要求
- PHP >= 8.2.0
- Composer
安装
将包添加到依赖项
composer require globyapp/odata-query-parser
示例
1. 使用 $select 过滤某些字段
在这个例子中,我们将使用 $select
OData 查询字符串命令来过滤 API 返回的字段。
use GlobyApp\OdataQueryParser\OdataQueryParser; $data = OdataQueryParser::parse('https://example.com/api/user?$select=id,name,age');
如果您检查 $data
,这将是什么
object(GlobyApp\OdataQueryParser\OdataQuery)#2 (6) { ["select":"GlobyApp\OdataQueryParser\OdataQuery":private]=> array(3) { [0]=> string(2) "id" [1]=> string(4) "name" [2]=> string(3) "age" } ... }
2. 使用非美元语法
在这个例子中,我们将使用这个库的独特功能:在不指定任何美元的情况下,仍然能够使用 OData v4 URL 查询参数语法。
use GlobyApp\OdataQueryParser\OdataQueryParser; $data = OdataQueryParser::parse("https://example.com/api/user?select=id,name,age", $withDollar = false);
如果您检查 $data
,这将是什么
object(GlobyApp\OdataQueryParser\OdataQuery)#2 (6) { ["select":"GlobyApp\OdataQueryParser\OdataQuery":private]=> array(3) { [0]=> string(2) "id" [1]=> string(4) "name" [2]=> string(3) "age" } ... }
API
OdataQueryParser::parse(string $url, bool $withDollar = true): OdataQuery;
参数
- string
$url
: 从中解析查询字符串的 URL。它应该是一个“完整”或“完整”的 URL,这意味着https://example.com
将通过,而example.com
将不会通过 - bool
$withDollar
: 如果您想解析查询字符串而不需要在每个键前添加$
标志,则将其设置为 false。
返回
一个 OdataQuery 对象
return = OdataQuery { select => array<string>, count => bool|null, top => int|null, skip => int|null, orderBy => array<OrderByClause>, filter => array<FilterClause> }; OrderByClause { property => string, direction => OrderDirection } OrderDirection = "ASC" | "DESC" FilterClause { property => string, operator => string, value => int|float|string|bool|null|array<int|float|string|bool|null> }
抛出
InvalidArgumentException
- 如果参数
$url
不是一个有效的 URL(请参阅参数描述以了解什么是有效的 URL) - 如果
$top
查询字符串值不是一个整数 - 如果
$top
查询字符串值小于 0 - 如果
$skip
查询字符串值不是一个整数 - 如果
$skip
查询字符串值小于 0 - 如果
$count
查询字符串值不是一个布尔值 - 如果
$orderby
的格式不正确(应该是属性,空格和方向) - 如果
$orderby
查询字符串值的方向既不是asc
或desc
(不区分大小写)- 这将抛出一个 InvalidDirectionException,继承自 InvalidArgumentException。
- 如果
$filter
的格式不正确(应该是属性,空格,运算符,空格和值) - 如果
$filter
查询字符串值的运算符不是eq
、ne
、gt
、ge
、lt
、le
或in
(不区分大小写)- 这将抛出一个 InvalidFilterOperatorException,继承自 InvalidArgumentException。
- 如果参数
LogicException
- 如果由输入值触发了未预见的边缘情况。例如,当正则表达式操作失败时。在正常操作中不应抛出。
- 如果发现边缘情况,请将其报告为一个问题。目前,我无法为它们编写测试用例,因为我不知道如何触发它们。
- 如果由输入值触发了未预见的边缘情况。例如,当正则表达式操作失败时。在正常操作中不应抛出。
已知问题
$filter
命令不会解析or
和函数(如substringof
的contains()
),因为我目前没有关注这一点($filter
的解析器过于简单,我应该找到创建 AST 的方法)。
感谢
请随意打开任何问题或 PR。
MIT © 2024