flow/jsonpath

此包已被弃用,不再维护。作者建议使用softcreatr/jsonpath包代替。

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

0.5.0 2019-07-15 17:23 UTC

README

该项目在此处不再维护。请前往https://github.com/SoftCreatR/JSONPath

JSONPath 构建状态

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

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

该项目旨在成为一个简洁简单的实现,以下为其目标

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

安装

PHP 7.1+

composer require flow/jsonpath

PHP 5.4 - 5.6

PHP 5.x的支持已弃用...当前版本应该可以工作,但所有单元测试都是在7.1+上运行的,并且支持可能会在未来任何时候被删除。

php-5.x中维护了一个遗留分支,可以按以下方式使用composer安装:"flow/jsonpath": "dev-php-5.x"

JSONPath示例

JSONPath 结果
$.store.books[*].author 商店中所有书的作者
$..author 所有作者
$.store..price 商店中所有物品的价格。
$..books[2] 第三本书
$..books[(@.length-1)] 按顺序的最后一本书。
$..books[-1:] 按顺序的最后一本书。
$..books[0,1] 前两本书
$..books[:2] 前两本书
$..books[::2] 从第一本书开始的每本书(每隔一本书)
$..books[1:6:3] 从1到6的每第三本书
$..books[?(@.isbn)] 过滤所有带有ISBN号的书籍
$..books[?(@.price<10)] 过滤所有价格低于10的书籍
$..* 数据中的所有元素(递归提取)

表达式语法

符号 描述
$ 根对象/元素(不是严格必要的)
@ 当前对象/元素
.[] 子操作符
.. 递归下降
* 通配符。所有子元素,无论它们的索引如何。
[,] 数组索引作为集合
[start:end:step] 从ES4/Python借用的数组切片操作符。
?() 通过脚本表达式过滤结果集
() 使用脚本表达式的结果作为索引

PHP使用

$data = ['people' => [['name' => 'Joe'], ['name' => 'Jane'], ['name' => 'John']]];
$result = (new JSONPath($data))->find('$.people.*.name'); // returns new JSONPath
// $result[0] === 'Joe'
// $result[1] === 'Jane'
// $result[2] === 'John'

魔术方法访问

选项标志 JSONPath::ALLOW_MAGIC 将指导 JSONPath 在检索值时,首先检查对象是否具有魔法 __get() 方法,如果有,则调用此方法。此功能有些不可靠,不太可预测,因为

  • 通配符和递归功能仅查看公共属性,并且无法感知哪些属性可以通过魔法访问
  • 没有对魔法方法的 property_exists 检查,因此具有魔法 __get() 的对象在检查属性是否存在时总是返回 true
  • 通过 __get() 抛出的任何错误或由检索引起的不可预测的行为都应由您自行处理
$jsonPath = new JSONPath($myObject, JSONPath::ALLOW_MAGIC);

有关更多示例,请查看 JSONPathTest.php 测试文件。

脚本表达式

脚本表达式不受原始作者的支持,因为

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

因此,这里列出的是受支持的查询表达式类型

[?(@._KEY_ _OPERATOR_ _VALUE_)] // <, >, !=, and ==
Eg.
[?(@.title == "A string")] //
[?(@.title = "A string")]
// A single equals is not an assignment but the SQL-style of '=='

已知问题

  • 此项目尚未实现多重字符串索引,例如 $[name,year]$["name","year"]。我对此功能的发布时间没有预期,并且需要对使用非常基本的正则表达式实现的解析器进行一些重写。

类似项目

Galbar/JsonPath-PHP 是 PHP 实现的一个项目,它执行此项目不执行的一些操作,并且是一个强大的替代方案

JMESPath 执行类似操作,功能丰富,并且有 PHP 实现

CakePHP 的 Hash 工具执行一些类似操作

原始 JsonPath 实现在 http://code.google.com/p/jsonpath 上可用,并且在此处重新托管以用于 composer Peekmo/JsonPath

ObjectPath (https://github.com/adriank/ObjectPath) 似乎是一个具有新名称和额外功能的 Python/JS 实现。

变更日志

0.5.0

  • 修复了切片符号(例如 [0:2:5] 等)。破坏了依赖于损坏实现的代码

0.3.0

  • 添加了 JSONPathToken 类作为值对象
  • 词法分析和重构
  • 更新了对递归标记 ("..") 的词法分析和过滤,以允许递归和过滤的组合,例如 $..[?(@.type == 'suburb')].name

0.2.1 - 0.2.5

  • 各种错误修复和清理

0.2.0

  • 添加了大量数组访问功能,以提供更多创造性的迭代和链式操作可能性

0.1.x

  • 初始化