softcreatr/jsonpath
Evaluate and query JSON with JSONPath in PHP. softcreatr/jsonpath lets you select, filter, and extract data from arrays/objects using familiar JSONPath expressions, making it easy to navigate complex nested structures for APIs, configs, and fixtures.
This is a JSONPath implementation for PHP that targets the de facto comparison suite/RFC semantics while keeping the API small, cached, and eval-free.
eval.ArrayAccess/traversables in any combination.in/nin/!in, deep equality, RFC-style null existence/value handling, and literal-only short-circuiting (e.g., ?(true), ?(false), && false, || true).Requires PHP 8.5 or newer.
composer require softcreatr/jsonpath:"^1.0"
Useful commands:
composer exec phpunit
composer phpstan
composer cs
| JSONPath | Result |
|---|---|
$.store.books[*].author |
the authors of all books in the store |
$..author |
all authors |
$.store..price |
the price of everything in the store. |
$..books[2] |
the third book |
$..books[(@.length-1)] |
the last book in order. |
$..books[-1:] |
the last book in order. |
$..books[0,1] |
the first two books |
$..books[title,year] |
multiple keys in a union |
$..books[:2] |
the first two books |
$..books[::2] |
every second book starting from first one |
$..books[1:6:3] |
every third book starting from 1 till 6 |
$..books[?(@.isbn)] |
filter all books with isbn number |
$..books[?(@.price<10)] |
filter all books cheaper than 10 |
$..books.length |
the amount of books |
$..* |
all elements in the data (recursively extracted) |
| Symbol | Description |
|---|---|
$ |
The root object/element (not strictly necessary) |
@ |
The current object/element |
. or [] |
Child operator |
.. |
Recursive descent |
* |
Wildcard. All child elements regardless their index. |
[,] |
Array indices as a set |
[start:end:step] |
Array slice operator borrowed from ES4/Python. |
?() |
Filters a result set by a comparison expression (constant expressions like ?(true)/?(false) are allowed; unsupported/empty filters evaluate to an empty result) |
() |
Uses the result of a comparison expression as the index |
<?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
)
*/
The options flag JSONPath::ALLOW_MAGIC will instruct JSONPath when retrieving a value to first check if an object
has a magic __get() method and will call this method if available. This feature is iffy and
not very predictable as:
property_exists check for magic methods so an object with a magic __get() will always return true when checking
if the property exists__get() is your own problem to deal with<?php
use Flow\JSONPath\JSONPath;
$myObject = (new Foo())->get('bar');
$jsonPath = new JSONPath($myObject, JSONPath::ALLOW_MAGIC);
Script execution is intentionally not supported:
eval, which we avoid.Supported filter/query patterns (200+ cases covered in the comparison suite):
[?(@._KEY_ _OPERATOR_ _VALUE_)]
Operators: ==, =, !=, <>, !==, <, >, <=, >=, =~, in, nin, !in
Examples:
[?(@.title == "A string")] // equality
[?(@.title = "A string")] // SQL-style equals
[?(@.price < 10)] // numeric comparisons
[?(@.title =~ /^a(nother)?/i)] // regex
[?(@.title in ["A","B"])] // membership
[?(@.title nin ["A"])] // not in
[?(@.title !in ["A"])] // alternate not in
[?(@.key == @.other)] // path-to-path comparison
[?(@.key == $.rootValue)] // root reference
[?(@)] or [?(@==@)] // truthy/tautology
[?(@.length)] // existence checks
[?(@['weird-key']=="ok")] // bracket-escaped keys and negative indexes
A full list of (un)supported filter/query patterns can be found in the JSONPath Comparison Cheatsheet.
FlowCommunications/JSONPath is the predecessor of this library by Stephen Frank
Other / Similar implementations can be found in the Wiki.
A list of changes can be found in the CHANGELOG.md file.
This package is Treeware. If you use it in production, then we ask that you buy the world a tree to thank us for our work. By contributing to the ecologi project, you’ll be creating employment for local families and restoring wildlife habitats.
How can I help you explore Laravel packages today?