softcreatr/jsonpath

JSONPath implementation for parsing, searching and flattening arrays

0.9.1 2024-06-01 09:15 UTC

This package is auto-updated.

Last update: 2024-10-31 00:17:53 UTC


README

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:

  • Object-oriented code (should be easier to manage or extend in future)
  • Expressions are parsed into tokens using code inspired by the Doctrine Lexer. The tokens are cached internally to avoid re-parsing the expressions.
  • There is no eval() in use
  • Any combination of objects/arrays/ArrayAccess-objects can be used as the data input which is great if you're de-serializing JSON in to objects or if you want to process your own data structures.

Installation

composer require softcreatr/jsonpath:"^0.9"

JSONPath Examples

Expression syntax

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:

  • wildcard and recursive features will only look at public properties and can't smell which properties are magically accessible
  • there is no property_exists check for magic methods so an object with a magic __get() will always return true when checking if the property exists
  • any errors thrown or unpredictable behaviour caused by fetching via __get() is your own problem to deal with
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:

  • This would only be achievable through eval (boo).
  • Using the script engine from different languages defeats the purpose of having a single expression evaluate the same way in different languages which seems like a bit of a flaw if you're creating an abstract expression syntax.

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

  • This project has not implemented multiple string indexes e.g. $[name,year] or $["name","year"]. I have no ETA on that feature, and it would require some re-writing of the parser that uses a very basic regex implementation.

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 ✨