supermetrics/jsonpath

使用灵活的 JSONPath 查询语言从解码的 JSON 文档中提取数据

dev-main 2024-09-27 09:33 UTC

This package is auto-updated.

Last update: 2024-09-27 09:57:46 UTC


README

Build status Code coverage

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 表达式语法

另请参阅 示例

性能基准

Chart showing a performance comparison between JsonPath-PHP, native PHP (JsonPath-PHP sometimes faster, sometimes slower), and the fastest tested PHP library (JsonPath-PHP always faster)

图表中的数字是在启用 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