softcreatr / jsonpath
JSONPath implementation for parsing, searching and flattening arrays
Fund package maintenance!
softcreatr
ecologi.com/softcreatr?r=61212ab3fc69b8eb8a2014f4
Installs: 22 034 350
Dependents: 32
Suggesters: 0
Security: 0
Stars: 149
Watchers: 6
Forks: 27
Open Issues: 37
Requires
- php: 8.1 - 8.4
- ext-json: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.58
- phpunit/phpunit: 10 - 12
- squizlabs/php_codesniffer: ^3.10
Replaces
README
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 returntrue
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 🌳
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.