globyapp/odata-query-parser

解析 OData v4 查询字符串,输出合适的 PHP 对象。

v1.1.0 2024-09-07 17:29 UTC

README

解析 OData v4 查询字符串,输出合适的 PHP 对象。

Packagist Version Packagist PHP from Packagist CI

摘要

关于

我只需要解析查询字符串,将 OData v4 命令转换为可理解的数组,以便我可以用它来制作一个 Laravel 扩展包,以便自动使用 Eloquent 根据解析的 OData v4 命令数组来过滤响应。

因为我没有看到专门处理解析查询字符串的包,并且看到 有些人自己做了但没有开源,所以我决定自己开始一个。

功能

  • 解析 URL 并返回数组
  • 支持 $select$top$skip$orderby$count
  • $filter 的部分支持(请参阅已知问题部分)
  • 您可以使用一种解析模式,让您解析这些关键字而不需要在其前面添加 $

要求

安装

将包添加到依赖项

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 查询字符串值的方向既不是 ascdesc(不区分大小写)
      • 这将抛出一个 InvalidDirectionException,继承自 InvalidArgumentException。
    • 如果 $filter 的格式不正确(应该是属性,空格,运算符,空格和值)
    • 如果 $filter 查询字符串值的运算符不是 eqnegtgeltlein(不区分大小写)
      • 这将抛出一个 InvalidFilterOperatorException,继承自 InvalidArgumentException。
  • LogicException
    • 如果由输入值触发了未预见的边缘情况。例如,当正则表达式操作失败时。在正常操作中不应抛出。
      • 如果发现边缘情况,请将其报告为一个问题。目前,我无法为它们编写测试用例,因为我不知道如何触发它们。

已知问题

  • $filter 命令不会解析 or 和函数(如 substringofcontains()),因为我目前没有关注这一点($filter 的解析器过于简单,我应该找到创建 AST 的方法)。

感谢

请随意打开任何问题或 PR。

MIT © 2024