软创/jsonpath

用于解析、搜索和展平数组的JSONPath实现

0.9.1 2024-06-01 09:15 UTC

This package is auto-updated.

Last update: 2024-08-31 09:49:59 UTC


README

Build Latest Release MIT licensed Plant Tree Codecov branch Code Climate maintainability

这是一个基于Stefan Goessner的JSONPath脚本的PHP JSONPath实现。

JSONPath是一种类似于XPath的表达式语言,用于过滤、展平和提取数据。

本项目旨在实现一个简洁且简单的实现,以下是其目标:

  • 面向对象代码(未来管理和扩展应更简单)
  • 表达式通过受到Doctrine Lexer启发的代码解析为令牌。令牌被内部缓存以避免重新解析表达式。
  • 没有使用eval()
  • 可以使用任何组合的对象/数组/ArrayAccess-对象作为数据输入,这对于将JSON反序列化为对象或处理自己的数据结构非常有用。

安装

composer require softcreatr/jsonpath:"^0.9"

JSONPath示例

表达式语法

PHP用法

使用数组

<?php
require_once __DIR__ . '/vendor/autoload.php';

$data = ['people' => [
    ['name' => 'Sascha'],
    ['name' => 'Bianca'],
    ['name' => 'Alexander'],
    ['name' => 'Maximilian'],
]];

print_r((new \Flow\JSONPath\JSONPath($data))->find('$.people.*.name')->getData());

/*
Array
(
    [0] => Sascha
    [1] => Bianca
    [2] => Alexander
    [3] => Maximilian
)
*/

使用对象

<?php
require_once __DIR__ . '/vendor/autoload.php';

$data = json_decode('{"name":"Sascha Greuel","birthdate":"1987-12-16","city":"Gladbeck","country":"Germany"}', false);

print_r((new \Flow\JSONPath\JSONPath($data))->find('$')->getData()[0]);

/*
stdClass Object
(
    [name] => Sascha Greuel
    [birthdate] => 1987-12-16
    [city] => Gladbeck
    [country] => Germany
)
*/

更多示例可以在Wiki中找到。

魔术方法访问

选项标志JSONPath::ALLOW_MAGIC会在检索值时指示JSONPath首先检查对象是否有魔术__get()方法,如果可用,则调用此方法。此功能iffy且不可预测,因为

  • 通配符和递归功能只会查看公共属性,并且无法识别哪些属性可以通过魔术方法访问
  • 没有对魔术方法进行property_exists检查,因此具有魔术__get()的对象在检查属性是否存在时始终返回true
  • 由通过__get()获取引起的任何错误或不可预测的行为都是您自己的问题
use Flow\JSONPath\JSONPath;

$myObject = (new Foo())->get('bar');
$jsonPath = new JSONPath($myObject, JSONPath::ALLOW_MAGIC);

更多示例,请参阅JSONPathTest.php测试文件。

脚本表达式

脚本表达式不支持,因为原始作者希望实现。

  • 这只能通过eval(boo)实现。
  • 使用不同语言的脚本引擎会破坏在多种语言中用单个表达式以相同方式评估的目的,这对于创建抽象表达式语法来说似乎是一个缺陷。

因此,以下是支持的查询表达式类型:

[?(@._KEY_ _OPERATOR_ _VALUE_)] // <, >, <=, >=, !=, ==, =~, in and nin
e.g.
[?(@.title == "A string")] //
[?(@.title = "A string")]
// A single equals is not an assignment but the SQL-style of '=='
[?(@.title =~ /^a(nother)? string$/i)]
[?(@.title in ["A string", "Another string"])]
[?(@.title nin ["A string", "Another string"])]

已知问题

  • 本项目尚未实现多个字符串索引,例如$[name,year]$["name","year"]。我无法提供该功能的预计时间表,并且它将需要重写使用非常基本的正则表达式实现的解析器。

类似项目

FlowCommunications/JSONPath是Stephen Frank的此库的先驱。

其他/类似实现可以在Wiki中找到。

变更日志

可以在CHANGELOG.md文件中找到更改列表。

许可证 🌳

MIT © 1-2.dev

此包为Treeware。如果您在生产中使用它,我们要求您为世界买一棵树以感谢我们的工作。通过为ecologi项目做出贡献,您将创造就业机会并为当地家庭创造就业机会,恢复野生动物栖息地。

贡献者 ✨