ropi/json-path-evaluator 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

ropi/json-path-evaluator

Composer 安装命令:

composer require ropi/json-path-evaluator

包简介

A JSONPath implementation for PHP

README 文档

README

This library is a PHP based implementation of JSONPath (RFC 9535).

It allows to evaluate JSONPath expressions directly on PHP objects and/or arrays.
This implementation passes all compliance tests of JSONPath Compliance Test Suite.

Requirements

  • PHP >= 8.1
  • ext-ctype
  • ext-intl
  • ext-mbstring

Table of contents

Installation

The library can be installed from a command line interface by using composer.

composer require ropi/json-path-evaluator

Examples

Get values

The following example shows how to get values that match a JSONPath.
The result is always an array of values that match the JSONPath. If there are no matches, an empty array is returned.

$data = json_decode('{ "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": 399
   }
 }
}');

$evaluator = new \Ropi\JsonPathEvaluator\JsonPathEvaluator();

$result = $evaluator->getValues($data, '$.store.book[*].author');
echo "Authors of all books in the store:\n" . json_encode($result, JSON_PRETTY_PRINT) . "\n";

$result = $evaluator->getValues($data, '$.store..price');
echo "Prices of everything in the store:\n" . json_encode($result, JSON_PRETTY_PRINT) . "\n";

$result = $evaluator->getValues($data, '$..book[-1]');
echo "Last book in order:\n" . json_encode($result, JSON_PRETTY_PRINT) . "\n";

$result = $evaluator->getValues($data, '$..book[0,1]');
echo "First two books with union operator:\n" . json_encode($result, JSON_PRETTY_PRINT) . "\n";

$result = $evaluator->getValues($data, '$..book[:2]');
echo "First two books with array slice operator:\n" . json_encode($result, JSON_PRETTY_PRINT) . "\n";

$result = $evaluator->getValues($data, '$..book[?@.isbn]');
echo "All books with an ISBN number:\n" . json_encode($result, JSON_PRETTY_PRINT) . "\n";

$result = $evaluator->getValues($data, '$..book[?@.price<10]');
echo "All books cheaper than 10:\n" . json_encode($result, JSON_PRETTY_PRINT) . "\n";

$result = $evaluator->getValues($data, '$..book[?search(@.isbn, "[1-3]$")]'); // regular expression
echo "All books where ISBN ends with 1, 2 or 3:\n" . json_encode($result, JSON_PRETTY_PRINT) . "\n";

The above example will output:

Authors of all books in the store:
[
    "Nigel Rees",
    "Evelyn Waugh",
    "Herman Melville",
    "J. R. R. Tolkien"
]
Prices of everything in the store:
[
    8.95,
    12.99,
    8.99,
    22.99,
    399
]
Last book in order:
[
    {
        "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
    }
]
First two books with union operator:
[
    {
        "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
    }
]
First two books with array slice operator:
[
    {
        "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
    }
]
All books with an ISBN number:
[
    {
        "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
    }
]
All books cheaper than 10:
[
    {
        "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
    },
    {
        "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
    }
]
All books where ISBN ends with 1, 2 or 3:
[
    {
        "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
    }
]

Get paths

The following example shows how to get value paths that match a JSONPath, where each value path is represented as normalized JSONPath according to section 2.7 of RFC 9535.
The result is always an array of matched paths. If there are no matches, an empty array is returned.

$data = json_decode('{ "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": 399
   }
 }
}');

$evaluator = new \Ropi\JsonPathEvaluator\JsonPathEvaluator();

$result = $evaluator->getPaths($data, '$.store.book[*].author');
echo "Paths of authors of all books in store:\n" . json_encode($result, JSON_PRETTY_PRINT) . "\n";

$result = $evaluator->getPaths($data, '$.store..price');
echo "Paths of prices of everything in the store:\n" . json_encode($result, JSON_PRETTY_PRINT) . "\n";

$result = $evaluator->getPaths($data, '$..book[?@.price<10]');
echo "Paths of all books cheaper than 10:\n" . json_encode($result, JSON_PRETTY_PRINT) . "\n";

The above example will output:

Paths of authors of all books in store:
[
    "$['store']['book'][0]['author']",
    "$['store']['book'][1]['author']",
    "$['store']['book'][2]['author']",
    "$['store']['book'][3]['author']"
]
Paths of prices of everything in the store:
[
    "$['store']['book'][0]['price']",
    "$['store']['book'][1]['price']",
    "$['store']['book'][2]['price']",
    "$['store']['book'][3]['price']",
    "$['store']['bicycle']['price']"
]
Paths of all books cheaper than 10:
[
    "$['store']['book'][0]",
    "$['store']['book'][2]"
]

Set values

The following example shows how to set/replace values.

$data = json_decode('{ "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": 399
   }
 }
}');

$evaluator = new \Ropi\JsonPathEvaluator\JsonPathEvaluator();

$numSet = $evaluator->setValues($data, '$..price', [10]);
echo "Set all $numSet prices to 10:\n" . json_encode($data, JSON_PRETTY_PRINT) . "\n";

$numSet = $evaluator->setValues($data, '$..price', [1, 2, 3]);
echo "Set all $numSet alternately to 1, 2 and 3:\n" . json_encode($data, JSON_PRETTY_PRINT) . "\n";

The above example will output:

Set all 5 prices to 10:
{
    "store": {
        "book": [
            {
                "category": "reference",
                "author": "Nigel Rees",
                "title": "Sayings of the Century",
                "price": 10
            },
            {
                "category": "fiction",
                "author": "Evelyn Waugh",
                "title": "Sword of Honour",
                "price": 10
            },
            {
                "category": "fiction",
                "author": "Herman Melville",
                "title": "Moby Dick",
                "isbn": "0-553-21311-3",
                "price": 10
            },
            {
                "category": "fiction",
                "author": "J. R. R. Tolkien",
                "title": "The Lord of the Rings",
                "isbn": "0-395-19395-8",
                "price": 10
            }
        ],
        "bicycle": {
            "color": "red",
            "price": 10
        }
    }
}
Set all 5 alternately to 1, 2 and 3:
{
    "store": {
        "book": [
            {
                "category": "reference",
                "author": "Nigel Rees",
                "title": "Sayings of the Century",
                "price": 1
            },
            {
                "category": "fiction",
                "author": "Evelyn Waugh",
                "title": "Sword of Honour",
                "price": 2
            },
            {
                "category": "fiction",
                "author": "Herman Melville",
                "title": "Moby Dick",
                "isbn": "0-553-21311-3",
                "price": 3
            },
            {
                "category": "fiction",
                "author": "J. R. R. Tolkien",
                "title": "The Lord of the Rings",
                "isbn": "0-395-19395-8",
                "price": 1
            }
        ],
        "bicycle": {
            "color": "red",
            "price": 2
        }
    }
}

Set values and create non-existent paths

The following example shows how to set values on non-existent paths.

$evaluator = new \Ropi\JsonPathEvaluator\JsonPathEvaluator();

// Create non-existent paths as stdClass objects
$data = json_decode('{}');
$evaluator->setValues($data, '$.deep.path.value', ["stdClassExample"], \Ropi\JsonPathEvaluator\NonExistentPathBehavior::CreateStdClass);
var_dump($data) . "\n";

// Create non-existent paths as arrays
$data = json_decode('[]');
$evaluator->setValues($data, '$.deep.path.value', ["arrayExample"], \Ropi\JsonPathEvaluator\NonExistentPathBehavior::CreateArray);
var_dump($data) . "\n";

The above example will output:

object(stdClass)#8 (1) {
  ["deep"]=>
  object(stdClass)#37 (1) {
    ["path"]=>
    object(stdClass)#32 (1) {
      ["value"]=>
      string(15) "stdClassExample"
    }
  }
}
array(1) {
  ["deep"]=>
  array(1) {
    ["path"]=>
    array(1) {
      ["value"]=>
      string(12) "arrayExample"
    }
  }
}

Delete paths

The following example shows how to delete/remove/unset paths that match a JSONPath.

$data = json_decode('{ "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": 399
   }
 }
}');

$evaluator = new \Ropi\JsonPathEvaluator\JsonPathEvaluator();

$numDeleted = $evaluator->deletePaths($data, '$.store.book[?@.price > 9]');
echo "Deleted all $numDeleted books that are more expensive than 9:\n" . json_encode($data, JSON_PRETTY_PRINT) . "\n";

The above example will output:

Deleted all 2 books in store that are more expensive than 9:
{
    "store": {
        "book": {
            "0": {
                "category": "reference",
                "author": "Nigel Rees",
                "title": "Sayings of the Century",
                "price": 8.95
            },
            "2": {
                "category": "fiction",
                "author": "Herman Melville",
                "title": "Moby Dick",
                "isbn": "0-553-21311-3",
                "price": 8.99
            }
        },
        "bicycle": {
            "color": "red",
            "price": 399
        }
    }
}

Custom function extensions

The following example shows how to register custom function extensions according to section 2.4 of RFC 9535.

$evaluator = new \Ropi\JsonPathEvaluator\JsonPathEvaluator();

$data = json_decode('{
    "values": [
        {"property": "valueA"},
        {"property": "valueB"}
    ]
}');

$evaluator = new \Ropi\JsonPathEvaluator\JsonPathEvaluator();

$evaluator->registerFunction('myFunction', function(\Ropi\JsonPathEvaluator\Types\AbstractValueType $parameter1) {
    if (!$parameter1 instanceof \Ropi\JsonPathEvaluator\Types\JsonValue) {
        return new \Ropi\JsonPathEvaluator\Types\LogicalFalse();
    }

    return $parameter1->getValue() === 'valueB'
        ? new \Ropi\JsonPathEvaluator\Types\LogicalTrue()
        : new \Ropi\JsonPathEvaluator\Types\LogicalFalse();
});

$result = $evaluator->getValues($data, '$.values[?myFunction(@.property)].property');
echo json_encode($result, JSON_PRETTY_PRINT);

The above example will output:

[
    "valueB"
]

ropi/json-path-evaluator 适用场景与选型建议

ropi/json-path-evaluator 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 94 次下载、GitHub Stars 达 0, 最近一次更新时间为 2023 年 12 月 15 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「json」 「path」 「accessor」 「expression」 「evaluator」 「jsonpath」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 ropi/json-path-evaluator 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 ropi/json-path-evaluator 我们能提供哪些服务?
定制开发 / 二次开发

基于 ropi/json-path-evaluator 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 94
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 25
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-12-15