supermetrics / jsonpath
使用灵活的 JSONPath 查询语言从解码的 JSON 文档中提取数据
Requires
- php: >=8.0,<8.5
This package is auto-updated.
Last update: 2024-09-27 09:57:46 UTC
README
JSONPath 是一种查询和从 JSON 中提取数据的高级语言,类似于 XML 的 XPath。
此 PHP 扩展程序受 Stefan Goessner 的原始实现 的启发,并旨在作为 PHP 中编写的 JSONPath 库的快速替代品。
目标受众
此扩展程序非常适合高度依赖 JSONPath 且可从原生 C 实现中受益的项目。其他 JSONPath 实现通常依赖于 eval() 和正则表达式,而 JsonPath-PHP 是一个更有效的词法分析器和语法分析器。在 C 中而不是在 PHP 中提取数据可显著提高性能。事实上,JsonPath-PHP 往往比手动遍历数组并选择匹配元素更快。
为了提高性能,必须承担将此扩展添加到 PHP 安装中的开销。如果您在无法安装 PHP 扩展的共享环境中运行 PHP 应用程序,我们建议您查看更方便的 PHP 实现,如 此、此 和 此。或者切换到您有更多控制权的环境。😉
安装
Linux 和 macOS
选项 1:使用 PECL 构建
$ pecl install jsonpath
有关如何使用 PECL 的更多说明,请参阅 PECL 文档。
选项 2:手动构建
将此存储库克隆到您选择的目录,然后运行
$ phpize $ ./configure --enable-jsonpath $ make $ TEST_PHP_ARGS="-q" make test $ sudo make install
启用扩展
$ sudo touch /etc/php.d/jsonpath.ini $ echo "extension=jsonpath.so" | sudo tee /etc/php.d/jsonpath.ini $ php -m | grep jsonpath
如果您正在运行带有 PHP-FPM 服务的 PHP,请重新启动它以使更改生效
$ sudo service php-fpm restart
Windows
有关预构建的 Windows DLL 的信息,请参阅 PHP 扩展存储库。
请记住将 extension=jsonpath 添加到您的 php.ini 以启用扩展。
有关安装 PHP 扩展的更多说明,请参阅 PECL 文档。
使用方法
<?php use JsonPath\JsonPath; use JsonPath\JsonPathException; $jsonPath = new JsonPath(); try { // Query a data array using a JSONPath expression string. // Returns an array of matching elements, or false if nothing was found. $result = $jsonPath->find($data, $selector); } catch (JsonPathException $exception) { echo $exception->getMessage(); // Usually a syntax error in the selector }
示例
<?php $json = <<<JSON { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } } JSON; $data = json_decode($json, true); $jsonPath = new \JsonPath\JsonPath(); echo "Example 1: - The authors of all books in the store: \n"; echo json_encode($jsonPath->find($data, "$.store.book[*].author"), JSON_PRETTY_PRINT); echo "\n\n"; /* [ "Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien" ] */ echo "Example 2 - All authors:\n"; echo json_encode($jsonPath->find($data, "$..author"), JSON_PRETTY_PRINT); echo "\n\n"; /* [ "Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien" ] */ echo "Example 3 - All things in the store:\n"; echo json_encode($jsonPath->find($data, "$.store.*"), JSON_PRETTY_PRINT); echo "\n\n"; /* [ [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], { "color": "red", "price": 19.95 } ] */ echo "Example 4 - The price of everything in the store:\n"; echo json_encode($jsonPath->find($data, "$.store..price"), JSON_PRETTY_PRINT); echo "\n\n"; /* [ 8.95, 12.99, 8.99, 22.99, 19.95 ] */ echo "Example 5 - The third book:\n"; echo json_encode($jsonPath->find($data, "$..book[2]"), JSON_PRETTY_PRINT); echo "\n\n"; /* [ { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 } ] */ echo "Example 6 - The title of the last book:\n"; echo json_encode($jsonPath->find($data, "$..book[-1].title"), JSON_PRETTY_PRINT); echo "\n\n"; /* [ "The Lord of the Rings" ] */ echo "Example 7 - Lookup by ISBN:\n"; echo json_encode($jsonPath->find($data, "$.store.book[?(@.isbn == '0-395-19395-8')]"), JSON_PRETTY_PRINT); echo "\n\n"; /* [ { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ] */ echo "Example 8 - Lookup by category and price:\n"; echo json_encode($jsonPath->find($data, "$.store.book[?(@.category == 'fiction' && @.price <= 15.00)]"), JSON_PRETTY_PRINT); echo "\n\n"; /* [ { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 } ] */ echo "Example 9 - Lookup by author using regular expression:\n"; echo json_encode($jsonPath->find($data, "$.store.book[?(@.author =~ /Tolkien$/)]"), JSON_PRETTY_PRINT); echo "\n\n"; /* [ { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ] */ echo "Example 10 - The titles of books without an ISBN:\n"; echo json_encode($jsonPath->find($data, "$.store.book[?(!@.isbn)].title"), JSON_PRETTY_PRINT); echo "\n\n"; /* [ "Sayings of the Century", "Sword of Honour" ] */
JSONPath 表达式语法
另请参阅 示例。
性能基准
图表中的数字是在启用 OPcache 和 JIT 的 PHP 8.1 上运行基准测试套件时获得的。
如果您想自己运行基准测试,请查看 jsonpath-benchmark 存储库。
许可证
JsonPath-PHP 是开源软件,根据 PHP License 3.01 许可。
测试
单元测试利用了 PHP 的核心和扩展测试框架。运行测试的推荐方法是
$ TEST_PHP_ARGS="-q" make test
JsonPath-PHP 实现了 JSONPath Comparison 测试套件。这些测试位于 tests/comparison_* 目录中。
要生成代码覆盖率报告,请安装 lcov,使用特殊的 --enable-code-coverage 标志构建扩展,然后在运行测试和处理代码覆盖率输出之前构建扩展。
$ ./configure --enable-jsonpath --enable-code-coverage $ make clean $ TEST_PHP_ARGS="-q" make test $ make lcov
然后您可以在 lcov_html/ 目录中找到覆盖率报告。
代码质量工具
在提交pull request之前,请运行代码格式化和代码检查器(并修复代码检查器报告的任何问题)。
您可以通过设置pre-commit钩子,在提交前自动检查代码格式和代码检查器。
make setup-pre-commit
格式化
代码格式化需要clang-format。
make format-code
代码检查
代码检查需要cppcheck。
make lint-code
贡献者
JsonPath-PHP是由Mike Kaminski创建并由Supermetrics和Mike Kaminski维护。
发现了一个错误,或者缺少某些功能?请提出问题或提交pull request。
