JSONPath 实现的分支,用于解析、搜索和扁平化数组

0.2.1 2023-05-25 13:51 UTC

This package is not auto-updated.

Last update: 2024-09-13 17:42:49 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.5 || ^0.7 || ^0.8"

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项目捐款,您将为当地家庭创造就业机会,并恢复野生动物栖息地。

贡献者 ✨