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

Overview

JSONPath for PHP

Build Status 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.5 || ^0.7"

JSONPath Examples

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[: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)

Expression syntax

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

PHP Usage

Using arrays


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

find('$')->getData()[0]); /* stdClass Object ( [name] => Sascha Greuel [birthdate] => 1987-12-16 [city] => Gladbeck [country] => Germany ) */">

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 ✨

Sascha
Sascha Greuel
LoΓ―c
LoΓ―c Leuilliot
Sergey/
Sergey
Alexandru
Alexandru Pătrănescu
Oleg
Oleg Andreyev
Comments
  • Fix php81 deprecated warnings

    Fix php81 deprecated warnings

    πŸ”€ Pull Request

    What does this PR do?

    Fix deprecated warnings for PHP 8.1:

    Deprecated: Return type of Flow\JSONPath\JSONPath::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice
    Exception:
    ErrorException: Deprecated: Return type of Flow\JSONPath\JSONPath::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /www/foe/libs/external/softcreatr/jsonpath/src/JSONPath.php:271
    

    Test Plan

    No automated test plan only manual testing done.

    Related PRs and Issues

    No related PRs or Issues

    opened by pbojan 13
  • Idea of multi index search

    Idea of multi index search

    This is the idea proposed within the code, I have commented the code for the indexing and added a regex for the multi index matching thanks for review in advance.

    enhancement good first issue hacktoberfest 
    opened by Darknez07 7
  • [Bug-68] added support for length on array

    [Bug-68] added support for length on array

    • added token value check for length only if named key doesn't exist
    • updated test case to show it working
    • bonus: fixed test case for working length checks on script expressions

    Resolves #68

    opened by Lukazar 5
  • :package: Resolve `symfony/error-handler` and PHP 8.1 deprecations

    :package: Resolve `symfony/error-handler` and PHP 8.1 deprecations

    πŸ”€ Pull Request

    What does this PR do?

    Resolves PHP 8.1 and symfony/error-handler deprecations:

    PHP Deprecated: Return type of Flow\JSONPath\JSONPath::offsetGet($offset) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /.../vendor/softcreatr/jsonpath/src/JSONPath.php on line 213

    PHP message: PHP Deprecated: Return type of Flow\JSONPath\JSONPath::current() should either be compatible with Iterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /.../vendor/softcreatr/jsonpath/src/JSONPath.php on line 253

    PHP message: PHP Deprecated: Return type of Flow\JSONPath\JSONPath::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /.../vendor/softcreatr/jsonpath/src/JSONPath.php on line 271

    Test Plan

    Didn't test it yet, but used the same changes previously with other packages and internal code with no errors. Probably enough to run code with PHP 8.1 with enabled error reporting (optional - with enabled symfony/error-handler) and check that there is no deprecations.

    Related PRs and Issues

    n/a

    opened by andrew-demb 3
  • [BUG-69] fixed in clause filter

    [BUG-69] fixed in clause filter

    • added trim to explode to support both 1,2,3 and 1, 2, 3 inputs
    • dropped in_array strict equality check to be in line with the other standard equality checks such as (== and !=)

    Resolves #69

    opened by Lukazar 2
  • remove phpunit from conflicting packages

    remove phpunit from conflicting packages

    conflict is used to mention conflicting production packages, not dev packages. From what I can tell, you are not exposing a production feature related to PHPUnit.

    Keeping it like it is right now doesn't allow installing your package in another system where dev requiements would have lower than 7 version of phpunit and I think it's an artificial conflict that should not exist.

    opened by drealecs 1
  • fix: make the class compliant with php 7.4+

    fix: make the class compliant with php 7.4+

    since php 7.4, usage of array_key_exists has been deprecated (even denied) on object (ArrayAccess included). this change is designed to address this specific case and convert all usage of ArrayAccess instance to base method (to prevent future conflicts of such thing)

    sourcing error trace :

    ErrorException: array_key_exists(): Using array_key_exists() on objects is deprecated. Use isset() or property_exists() instead in /var/www/seat4/vendor/softcreatr/jsonpath/src/AccessHelper.php:68
    Stack trace:
    #0 /var/www/seat4/vendor/softcreatr/jsonpath/src/AccessHelper.php(68): Illuminate\Foundation\Bootstrap\HandleExceptions->handleError()
    #1 /var/www/seat4/vendor/softcreatr/jsonpath/src/Filters/IndexFilter.php(33): Flow\JSONPath\AccessHelper::keyExists()
    #2 /var/www/seat4/vendor/softcreatr/jsonpath/src/JSONPath.php(77): Flow\JSONPath\Filters\IndexFilter->filter()
    #3 /var/www/seat4/vendor/eveseat/eveapi/src/Mapping/DataMapping.php(65): Flow\JSONPath\JSONPath->find()
    #4 /var/www/seat4/vendor/eveseat/eveapi/src/Jobs/Calendar/Detail.php(97): Seat\Eveapi\Mapping\DataMapping::make()
    #5 /var/www/seat4/vendor/laravel/framework/src/Illuminate/Support/Traits/EnumeratesValues.php(176): Seat\Eveapi\Jobs\Calendar\Detail->Seat\Eveapi\Jobs\Calendar\{closure}()
    #6 /var/www/seat4/vendor/eveseat/eveapi/src/Jobs/Calendar/Detail.php(111): Illuminate\Support\Collection->each()
    #7 /var/www/seat4/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Seat\Eveapi\Jobs\Calendar\Detail->handle()
    

    official documentation

    πŸ”€ Pull Request

    What does this PR do?

    since php 7.4, usage of array_key_exists has been deprecated (even denied) on object (ArrayAccess included). this change is designed to address this specific case and convert all usage of ArrayAccess instance to its base methods (to prevent any similar conflict in futur core refactor)

    Test Plan

    • deploy any php version lower than php 7.4

    • create a simple ArrayObject build over a json result

    • try to retrieve any value from it using the library -> pass

    • deploy any php version upper or equal to 7.4

    • create a simple ArrayObject build over a json result

    • try to retrieve any value from it using the library -> getting an ErrorException

    • apply fix

    • redo the test

    • pass

    $json = '{"date": "2016-06-26T21:00:00Z","duration": 60,"event_id": 1386435,"importance": 1,"owner_id": 1,"owner_name": "EVE System","owner_type": "eve_server","response": "Undecided","text": "o7: The EVE Online Show features latest developer news, fast paced action, community overviews and a lot more with CCP Guard and CCP Mimic. Join the thrilling o7 live broadcast at 20:00 EVE time (=UTC) on <a href=\"http://www.twitch.tv/ccp\">EVE TV</a>. Don\'t miss it!","title": "o7 The EVE Online Show"}';
    $array = new ArrayObject(json_decode($json, true), ArrayObject::ARRAY_AS_PROPS);
    
    $json_path = new \Flow\JSONPath\JSONPath($array);
    
    // get date value - expected `2016-06-26T21:00:00Z`
    $value = $json_path->find('date')->first();
    
    // set date value
    $json_path->offsetSet('date', 'test')
    
    // get date value - expected `test`
    $value = $json_path->find('date')->first();
    
    
    enhancement good first issue 
    opened by warlof 1
Releases(0.8.1)
Owner
Sascha Greuel
Sascha Greuel
Php-file-iterator - FilterIterator implementation that filters files based on a list of suffixes, prefixes, and other exclusion criteria.

php-file-iterator Installation You can add this library as a local, per-project dependency to your project using Composer: composer require phpunit/ph

Sebastian Bergmann 7.1k Jan 3, 2023
A "from scratch" PHP-based implementation of Event-Sourcing

In here, you will find a "from scratch" PHP-based implementation of Event-Sourcing, kept to a minimum on purpose, to allow workshop attendees to explore and experiment with its concepts.

Marco Pivetta 94 Jan 1, 2023
Simple customizable captcha script for bot prevention in php language.

phpCaptcha Simple customizable captcha script for bot prevention in php language. Usage <?php session_start(); $status = ""; if ($_SESSION['captcha']

Π€ΠΈΠ»ΠΈΠΏ Арсовски 11 Oct 10, 2022
Use Ray in any PHP script without requiring it in your projects.

Global Ray Use Ray in any PHP script without requiring it in your projects. Require this package globally with Composer: composer global require cuyz/

Team CuyZ 26 Jun 5, 2022
This shell script and PHP file create a browseable HTML site from the Zig standard library source.

Browseable Zig standard library This shell script and PHP file create a browseable HTML site from the Zig standard library source. The idea is to inve

Dave Gauer 3 Mar 20, 2022
PHP script for detecting browser details

Browser-details PHP script for detecting Your IP Address / Hostname, Browser/Computer Properties and Browser Headers. (Works with PHP 4, PHP 5, PHP 7,

Szerver.hu 5 Oct 15, 2022
A hacky PHP script to download posts, images, videos and framework grading from Parent Zone

ParentZoneDownloader A hacky PHP script to download posts, images, videos and framework grading from Parent Zone Pre-Requisites Tested on PHP 7.4, but

null 2 Sep 6, 2021
This PHP script optimizes the speed of your RAM memory

β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–‘β–ˆβ–ˆβ•—β–‘β–‘β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–‘β–ˆβ–ˆβ•—β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–‘β–ˆβ–ˆβ–ˆβ•—β–‘β–‘β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–‘β–‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ•—β–‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”

Γ‰rik Freitas 7 Feb 12, 2022
A PHP library that can be used manually as well as a CLI script that you can just run on your file

Run phpcs on files and only report new warnings/errors compared to the previous version. This is both a PHP library that can be used manually as well

Payton Swick 20 Aug 4, 2022
A PHP script that converts PMMP-3 Plugins into PMMP-4 plugins

This script tries to convert pm3 plugins to pm4 as good as possible, but sadly not perfect. Please open issues if you find any unexpected behaviour, to help improving this script.

null 43 Dec 3, 2022
PHP Website script that allows users to sell files for Bitcoin. Admin panel included. (earn from fees)

SatoshiBox Clone PHP Website script that allows users to sell files for Bitcoin. Admin panel included. Setup You will need a MySQL database, an operat

wnet 4 Dec 18, 2022
A small PHP Script to protect your site against DDoS attack .

Anti-DDoS A small PHP Script to protect your site against DDoS attack. Description Most of bots can't execute JavaScript code or can execute code part

Arman Msv 3 Dec 20, 2022
A comprehensive library for generating differences between two strings in multiple formats (unified, side by side HTML etc). Based on the difflib implementation in Python

PHP Diff Class Introduction A comprehensive library for generating differences between two hashable objects (strings or arrays). Generated differences

Chris Boulton 708 Dec 25, 2022
Simple WHOIS script with beautiful design.

Simple PHP Whois It is ideal in terms of design and has easy operation. / Tasarım açısından idealdir ve kullanımı kolaydır. It has a simple interface.

Raiven 1 Jul 16, 2022
This script allows to bypass Oracle Cloud Infrastructure 'Out of host capacity' error immediately when additional OCI capacity will appear in your Home Region / Availability domain.

Resolving Oracle Cloud "Out of Capacity" issue and getting free VPS with 4 ARM cores / 24GB of memory Very neat and useful configuration was recently

Alexander Hitrov 323 Jan 6, 2023
A script to retrieve data from a Netatmo weather station and display it in a Mac menu bar.

weathermenu A script to retrieve data from a Netatmo weather station and display it in a Mac menu bar. Intended for use with SwiftBar. Configuration N

Dan Moren 4 Nov 4, 2021
⌚ Watch your RAM in real time with this script ⌚

PHP-MemWatch Watch your RAM in real time, with this script! * Substitute of watch -n 1 free -m How to use: 1Β° Download this project 2Β° Extract to your

Γ‰rik Freitas 4 Dec 5, 2021
Composer script handling your ignored parameter file

Managing your ignored parameters with Composer This tool allows you to manage your ignored parameters when running a composer install or update. It wo

Incenteev 921 Nov 21, 2022
Pat eu cookies law - 🌝 EU Cookie Law Compliance: A Textpattern plugin (or standalone script) for Third-Party Cookies (RGPD compliance)

pat_eu_cookies_law EU Cookie Law Compliance: A Textpattern plugin (or a standalone script) for Third-Party Cookies. A simple solution that respects th

Patrick LEFEVRE 3 Aug 16, 2020