Home

Awesome

JSONPath for PHP 8.1+

Build Latest Release MIT licensed Plant Tree Codecov branch Code Climate maintainability

This is a JSONPath implementation for PHP based on Stefan Goessner's JSONPath script.

JSONPath is an XPath-like expression language for filtering, flattening and extracting data.

This project aims to be a clean and simple implementation with the following goals:

Installation

composer require softcreatr/jsonpath:"^0.9"

JSONPath Examples

JSONPathResult
$.store.books[*].authorthe authors of all books in the store
$..authorall authors
$.store..pricethe 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[: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.lengththe amount of books
$..*all elements in the data (recursively extracted)

Expression syntax

SymbolDescription
$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 script expression
()Uses the result of a script expression as the index

PHP Usage

Using arrays

<?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
)
*/

Using objects

<?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
)
*/

More examples can be found in the Wiki

Magic method access

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:

use Flow\JSONPath\JSONPath;

$myObject = (new Foo())->get('bar');
$jsonPath = new JSONPath($myObject, JSONPath::ALLOW_MAGIC);

For more examples, check the JSONPathTest.php tests file.

Script expressions

Script expressions are not supported as the original author intended because:

So here are the types of query expressions that are supported:

[?(@._KEY_ _OPERATOR_ _VALUE_)] // <, >, <=, >=, !=, ==, =~, in and nin
e.g.
[?(@.title == "A string")] //
[?(@.title = "A string")]
// A single equals is not an assignment but the SQL-style of '=='
[?(@.title =~ /^a(nother)? string$/i)]
[?(@.title in ["A string", "Another string"])]
[?(@.title nin ["A string", "Another string"])]

Known issues

Similar projects

FlowCommunications/JSONPath is the predecessor of this library by Stephen Frank

Other / Similar implementations can be found in the Wiki.

Changelog

A list of changes can be found in the CHANGELOG.md file.

License 🌳

MIT © 1-2.dev

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.

Contributors ✨

<table> <tr> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <a href=https://github.com/SoftCreatR> <img src=https://avatars.githubusercontent.com/u/81188?v=4 width="100;" alt=Sascha Greuel/> <br /> <sub style="font-size:14px"><b>Sascha Greuel</b></sub> </a> </td> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <a href=https://github.com/Schrank> <img src=https://avatars.githubusercontent.com/u/379680?v=4 width="100;" alt=Fabian Blechschmidt/> <br /> <sub style="font-size:14px"><b>Fabian Blechschmidt</b></sub> </a> </td> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <a href=https://github.com/warlof> <img src=https://avatars.githubusercontent.com/u/648753?v=4 width="100;" alt=Loïc Leuilliot/> <br /> <sub style="font-size:14px"><b>Loïc Leuilliot</b></sub> </a> </td> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <a href=https://github.com/SG5> <img src=https://avatars.githubusercontent.com/u/3931761?v=4 width="100;" alt=Sergey/> <br /> <sub style="font-size:14px"><b>Sergey</b></sub> </a> </td> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <a href=https://github.com/drealecs> <img src=https://avatars.githubusercontent.com/u/209984?v=4 width="100;" alt=Alexandru Pătrănescu/> <br /> <sub style="font-size:14px"><b>Alexandru Pătrănescu</b></sub> </a> </td> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <a href=https://github.com/oleg-andreyev> <img src=https://avatars.githubusercontent.com/u/1244112?v=4 width="100;" alt=Oleg Andreyev/> <br /> <sub style="font-size:14px"><b>Oleg Andreyev</b></sub> </a> </td> </tr> <tr> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <a href=https://github.com/rcjsuen> <img src=https://avatars.githubusercontent.com/u/15629116?v=4 width="100;" alt=Remy Suen/> <br /> <sub style="font-size:14px"><b>Remy Suen</b></sub> </a> </td> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <a href=https://github.com/esomething> <img src=https://avatars.githubusercontent.com/u/64032?v=4 width="100;" alt=esomething/> <br /> <sub style="font-size:14px"><b>esomething</b></sub> </a> </td> </tr> </table>