Skip to content

Commit b940e79

Browse files
committed
initial commit 🚀
0 parents  commit b940e79

23 files changed

+3071
-0
lines changed

‎.github/workflows/Test.yml‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
name: Test
3+
4+
on:
5+
push:
6+
paths:
7+
- '*.php'
8+
- 'composer.json'
9+
pull_request:
10+
paths:
11+
- '*.php'
12+
- 'composer.json'
13+
14+
jobs:
15+
run:
16+
runs-on: ubuntu-latest
17+
strategy:
18+
matrix:
19+
php: [ '7.2', '7.3', '7.4', '8.0' ]
20+
name: PHP ${{ matrix.php-versions }} Test
21+
22+
steps:
23+
- name: Git checkout
24+
uses: actions/checkout@v2
25+
26+
- name: Setup PHP
27+
uses: shivammathur/setup-php@v2
28+
with:
29+
php-version: ${{ matrix.php }}
30+
extensions: json
31+
coverage: none
32+
tools: phpunit
33+
env:
34+
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35+
36+
- name: Setup problem matchers for PHPUnit
37+
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
38+
39+
- name: Install dependencies
40+
run: composer install --prefer-dist --no-interaction --no-suggest
41+
42+
- name: Execute tests
43+
run: vendor/bin/phpunit --verbose

‎.gitignore‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.idea
2+
.phpunit.result.cache
3+
vendor
4+
.php_cs.cache
5+
composer.lock

‎LICENSE‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
MIT License
2+
3+
Original work - Copyright (c) 2018 Flow Communications
4+
Modified work - Copyright (c) 2020 1-2.dev
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.

‎README.md‎

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
JSONPath ![Test](https://github.com/SoftCreatR/JSONPath/workflows/Test/badge.svg)
2+
=============
3+
4+
This is a [JSONPath](http://goessner.net/articles/JsonPath/) implementation for PHP based on Stefan Goessner's JSONPath script.
5+
6+
JSONPath is an XPath-like expression language for filtering, flattening and extracting data.
7+
8+
This project aims to be a clean and simple implementation with the following goals:
9+
10+
- Object-oriented code (should be easier to manage or extend in future)
11+
- Expressions are parsed into tokens using code inspired by the Doctrine Lexer. The tokens are cached internally to avoid re-parsing the expressions.
12+
- There is no `eval()` in use
13+
- 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.
14+
15+
Installation
16+
---
17+
18+
**PHP 7.2+**
19+
```bash
20+
composer require softcreatr/jsonpath
21+
```
22+
**PHP < 7.2**
23+
24+
Support for PHP < 7.2 has been completely dropped. A legacy branch is maintained in the original repository in php-5.x and can be composer-installed as follows: `"flow/jsonpath": "dev-php-5.x"`
25+
26+
JSONPath Examples
27+
---
28+
29+
JSONPath | Result
30+
--------------------------|-------------------------------------
31+
`$.store.books[*].author` | the authors of all books in the store
32+
`$..author` | all authors
33+
`$.store..price` | the price of everything in the store.
34+
`$..books[2]` | the third book
35+
`$..books[(@.length-1)]` | the last book in order.
36+
`$..books[-1:]` | the last book in order.
37+
`$..books[0,1]` | the first two books
38+
`$..books[:2]` | the first two books
39+
`$..books[::2]` | every second book starting from first one
40+
`$..books[1:6:3]` | every third book starting from 1 till 6
41+
`$..books[?(@.isbn)]` | filter all books with isbn number
42+
`$..books[?(@.price<10)]` | filter all books cheapier than 10
43+
`$..*` | all elements in the data (recursively extracted)
44+
45+
46+
Expression syntax
47+
---
48+
49+
Symbol | Description
50+
----------------------|-------------------------
51+
`$` | The root object/element (not strictly necessary)
52+
`@` | The current object/element
53+
`.` or `[]` | Child operator
54+
`..` | Recursive descent
55+
`*` | Wildcard. All child elements regardless their index.
56+
`[,]` | Array indices as a set
57+
`[start:end:step]` | Array slice operator borrowed from ES4/Python.
58+
`?()` | Filters a result set by a script expression
59+
`()` | Uses the result of a script expression as the index
60+
61+
PHP Usage
62+
---
63+
64+
```php
65+
$data = ['people' => [['name' => 'Joe'], ['name' => 'Jane'], ['name' => 'John']]];
66+
$result = (new JSONPath($data))->find('$.people.*.name'); // returns new JSONPath
67+
// $result[0] === 'Joe'
68+
// $result[1] === 'Jane'
69+
// $result[2] === 'John'
70+
```
71+
72+
### Magic method access
73+
74+
The options flag `JSONPath::ALLOW_MAGIC` will instruct JSONPath when retrieving a value to first check if an object
75+
has a magic `__get()` method and will call this method if available. This feature is *iffy* and
76+
not very predictable as:
77+
78+
- wildcard and recursive features will only look at public properties and can't smell which properties are magically accessible
79+
- there is no `property_exists` check for magic methods so an object with a magic `__get()` will always return `true` when checking
80+
if the property exists
81+
- any errors thrown or unpredictable behaviour caused by fetching via `__get()` is your own problem to deal with
82+
83+
```php
84+
$jsonPath = new JSONPath($myObject, JSONPath::ALLOW_MAGIC);
85+
```
86+
87+
For more examples, check the JSONPathTest.php tests file.
88+
89+
Script expressions
90+
-------
91+
92+
Script expressions are not supported as the original author intended because:
93+
94+
- This would only be achievable through `eval` (boo).
95+
- Using the script engine from different languages defeats the purpose of having a single expression evaluate the same way in different
96+
languages which seems like a bit of a flaw if you're creating an abstract expression syntax.
97+
98+
So here are the types of query expressions that are supported:
99+
100+
[?(@._KEY_ _OPERATOR_ _VALUE_)] // <, >, !=, and ==
101+
Eg.
102+
[?(@.title == "A string")] //
103+
[?(@.title = "A string")]
104+
// A single equals is not an assignment but the SQL-style of '=='
105+
106+
Known issues
107+
------
108+
109+
- This project has not implemented multiple string indexes eg. `$[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.
110+
111+
Similar projects
112+
----------------
113+
114+
[FlowCommunications/JSONPath](https://github.com/FlowCommunications/JSONPath) is the predecessor of this library by Stephen Frank
115+
116+
[Galbar/JsonPath-PHP](https://github.com/Galbar/JsonPath-PHP) is a PHP implementation that does a few things this project doesn't and is a strong alternative
117+
118+
[JMESPath](https://github.com/jmespath) does similiar things, is full of features and has a PHP implementation
119+
120+
The [Hash](http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html) utility from CakePHP does some similar things
121+
122+
The original JsonPath implementations is available at [http://code.google.com/p/jsonpath]() and re-hosted for composer
123+
here [Peekmo/JsonPath](https://github.com/Peekmo/JsonPath).
124+
125+
[ObjectPath](http://objectpath.org) ([https://github.com/adriank/ObjectPath]()) appears to be a Python/JS implementation with a new name and extra features.
126+
127+
Changelog
128+
---------
129+
130+
### 0.6.0
131+
- Dropped support for PHP < 7.2
132+
- Switched from (broken) PSR-0 to PSR-4
133+
- Updated PHPUnit to 8.5 / 9.4
134+
- Updated tests
135+
- Added missing PHPDoc blocks
136+
- Added return type hints
137+
- Moved from Travis to GitHub actions
138+
139+
### 0.5.0
140+
- Fixed the slice notation (eg. [0:2:5] etc.). **Breaks code relying on the broken implementation**
141+
142+
### 0.3.0
143+
- Added JSONPathToken class as value object
144+
- Lexer clean up and refactor
145+
- Updated the lexing and filtering of the recursive token ("..") to allow for a combination of recursion
146+
and filters, eg. $..[?(@.type == 'suburb')].name
147+
148+
### 0.2.1 - 0.2.5
149+
- Various bug fixes and clean up
150+
151+
### 0.2.0
152+
- Added a heap of array access features for more creative iterating and chaining possibilities
153+
154+
### 0.1.x
155+
- Init
156+
157+
License
158+
---------
159+
160+
[MIT](LICENSE)

‎composer.json‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"name": "softcreatr/jsonpath",
3+
"description": "JSONPath implementation for parsing, searching and flattening arrays",
4+
"version": "0.6.0",
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Stephen Frank",
9+
"email": "[email protected]",
10+
"homepage": "https://prismaticbytes.com",
11+
"role": "Developer"
12+
},
13+
{
14+
"name": "Sascha Greuel",
15+
"email": "[email protected]",
16+
"homepage": "http://1-2.dev",
17+
"role": "Developer"
18+
}
19+
],
20+
"require": {
21+
"php": ">=7.2",
22+
"ext-json": "*"
23+
},
24+
"replace": {
25+
"flow/jsonpath": "*"
26+
},
27+
"require-dev": {
28+
"phpunit/phpunit": "^8 || ^9"
29+
},
30+
"config": {
31+
"optimize-autoloader": true,
32+
"preferred-install": "dist"
33+
},
34+
"autoload": {
35+
"psr-4": {
36+
"Flow\\JSONPath\\": "src/"
37+
}
38+
},
39+
"autoload-dev": {
40+
"psr-4": {
41+
"Flow\\JSONPath\\Test\\": "tests/"
42+
}
43+
},
44+
"minimum-stability": "stable",
45+
"support": {
46+
"email": "[email protected]",
47+
"issues": "https://github.com/SoftCreatR/JSONPath/issues",
48+
"source": "https://github.com/SoftCreatR/JSONPath"
49+
}
50+
}

‎phpunit.xml.dist‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.5/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
beStrictAboutOutputDuringTests="true"
6+
beStrictAboutTodoAnnotatedTests="true"
7+
verbose="true">
8+
<testsuites>
9+
<testsuite name="default">
10+
<directory>tests</directory>
11+
</testsuite>
12+
</testsuites>
13+
14+
<filter>
15+
<whitelist processUncoveredFilesFromWhitelist="true">
16+
<directory suffix=".php">src</directory>
17+
</whitelist>
18+
</filter>
19+
</phpunit>

0 commit comments

Comments
 (0)