messere / php-value-mask
提取数组/对象值的子集
0.1.2
2021-02-11 11:58 UTC
Requires
- php: ^7.1 || ^8.0
- ext-json: *
Requires (Dev)
- phpmd/phpmd: ^2.6
- phpunit/phpunit: ^7.0 || ^8.0
- squizlabs/php_codesniffer: ^3.3
This package is auto-updated.
Last update: 2024-09-11 19:57:32 UTC
README
目的
Google在其API性能提示中,建议通过过滤响应中的未使用字段来限制所需的带宽。他们的API支持额外的URL参数fields
,该参数要求API只包含响应中的特定字段。
fields
参数遵循简单的语法,允许查询嵌套键、多个键或使用通配符包含所有字段(请参阅下文的语法和文法部分)。
此库实现了fields
参数的解析和对数组/对象的过滤。
另请参阅:基于此库的PSR-15兼容中间件:[Partial Response PSR-15 Middleware](https://github.com/Messere/partial-response-middleware)
使用示例
<?php require_once 'vendor/autoload.php'; use messere\phpValueMask\Parser\Parser; use messere\phpValueMask\Parser\ParserException; $parser = new Parser(); $input = [ 'id' => 1, 'resource' => 'book', 'title' => 'Good Omens', 'identifiers' => (object)[ 'isbn' => 'ISBN 83-85100-63-6', 'amazon' => '0060853980', ], 'authors' => [ [ 'firstName' => 'Terry', 'lastName' => 'Pratchett' ], [ 'firstName' => 'Neil', 'lastName' => 'Gaiman' ], ], 'year' => [ 'us' => 1990, 'uk' => 1990, 'pl' => 1992, ], 'publisher' => [ 'us' => 'Workman', 'uk' => 'Gollancz', 'pl' => 'CIA-Books-SVARO', ], ]; $filter = 'title,identifiers/isbn,authors/firstName,*(us,uk),keywords'; try { $filteredInput = $parser->parse($filter)->filter($input); print_r($filteredInput); } catch (ParserException $e) { echo 'Parser error: ' . $e->getMessage(); }
让我们分析使用的过滤器元素
title
匹配顶级元素具有键title ('Good Omens')identifiers/isbn
匹配顶级元素identifiers
,然后包含从匹配对象中匹配的isbn
元素 ('ISBN 83-85100-63-6')authors/firstName
查找位于键authors
下的元素数组(列表),并检查所有元素,从每个元素中提取firstName
。 ('Terry' 和 'Neil')*(us,uk)
检查所有属性并提取字段us
和uk
。 ('1990' 和 '1990' 来自year
元素,'Workman', 'Gollancz' 来自publisher
)keywords
没有匹配任何内容,并且被静默忽略。
因此,我们期望以下输出
Array
(
[title] => Good Omens
[identifiers] => Array
(
[isbn] => ISBN 83-85100-63-6
)
[authors] => Array
(
[0] => Array
(
[firstName] => Terry
)
[1] => Array
(
[firstName] => Neil
)
)
[year] => Array
(
[us] => 1990
[uk] => 1999
)
[publisher] => Array
(
[us] => Workman
[uk] => Gollancz
)
)
准备序列化为JSON
等。
请注意,库保留了值的结构/嵌套,但不一定是值的类型 - 所有对象都转换为关联数组,对象公共属性作为键。
语法
a
选择输入中的键a
a,b,c
逗号分隔列表的元素:选择键a
、b
和c
a/b/c
嵌套元素:从父元素a
中选择键c
,该父元素本身具有父元素b
a(b,c)
多个元素:从父元素a
中选择元素b
和c
a(b,c/d)
多个元素:从父元素a
中选择元素b
和嵌套在c
中的元素d
a/*/c
通配符:从元素a
的所有子元素中选择元素c
*(b,c)
通配符:从任何父元素中选择元素b
和c
等等。请参阅测试以获取更多示例以及无效过滤器的示例。
文法
由于Google没有提供其“fields”语言的详细文法,此包使用以下任意选择的规则,在作者的看来,这些规则与原始作者的意图非常相似。
用EBNF表示法
Mask = MaskElement | MaskElement , "," , Mask ;
MaskElement = ArrayOfMasks | NestedKeys ;
ArrayOfMasks = Key , "(" , Mask , ")" ;
NestedKeys = Key , [ "/" , NestedKeys ] ;
Key = Wildcard | Identifier ;
Identifier = Letter , { Letter | Digit }
Wildcard = "*" ;
Letter = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" |
"N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" |
"a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" |
"n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" |
"_";
Digit = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "0" ;
致谢
库受到以下启发:
- Google的API性能提示。
- 类似的JavaScript库:[nemtsov/json-mask](https://github.com/nemtsov/json-mask)