Skip to content

Commit 64bdf2a

Browse files
committed
initial commit
1 parent f3ae79e commit 64bdf2a

File tree

4 files changed

+325
-2
lines changed

4 files changed

+325
-2
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/vendor/

Diff for: README.md

+156-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,156 @@
1-
# jsonparser
2-
PHP JSON Parser to ease handling JSON
1+
# PHP JSON Parser
2+
## Introduction
3+
Welcome to the PHP JSON Library, a simple tool for handling JSON data in your PHP applications. This library provides a set of functions for reading JSON data from strings or files, manipulating JSON data, and conveniently handling cases where a key doesn't exist in your JSON structure by returning a default value.
4+
5+
## Features
6+
7+
- **Read JSON from String**: Easily parse JSON data from a string and work with it within your PHP application.
8+
9+
- **Read JSON from File**: Quickly read JSON data from a file, simplifying the process of working with external JSON files.
10+
11+
- **Manipulate JSON Data**: Perform various operations on your JSON data, such as adding, updating, or removing keys, all with a simple and intuitive API.
12+
13+
- **Default Value Handling**: Handle cases where a JSON key doesn't exist by specifying a default value, preventing unexpected errors in your code.
14+
15+
## Installation
16+
17+
To get started, you can install the library using [Composer](https://getcomposer.org):
18+
19+
```bash
20+
composer require gemul/jsonparser
21+
```
22+
23+
## Usage
24+
### 1. Load JSON Data
25+
26+
Reading JSON from String
27+
```php
28+
$json = new \Gemul\JsonParser($json_string);
29+
```
30+
or from JSON file
31+
```php
32+
$json = new \Gemul\JsonParser(storage_path('/app/public/dummy.json'));
33+
```
34+
you can alson define separator string used for traversing the json tree, in constructor's second parameter (default ".").
35+
```php
36+
$json = new \Gemul\JsonParser($json_string,'->');
37+
```
38+
39+
### 2. Getting JSON data
40+
41+
Given this json structure:
42+
```json
43+
{
44+
"openapi": "3.0.3",
45+
"info": {
46+
"title": "Swagger Petstore - OpenAPI 3.0",
47+
"description": "This is a sample",
48+
"contact": {
49+
"email": "[email protected]"
50+
}
51+
},
52+
"externalDocs": {
53+
"description": "Find out more about Swagger",
54+
"url": "http://swagger.io"
55+
},
56+
"servers": [
57+
{
58+
"url": "https://petstore2.swagger.io/api/v2"
59+
},
60+
{
61+
"url": "https://petstore3.swagger.io/api/v3"
62+
}
63+
],
64+
...
65+
}
66+
```
67+
you can use ```getItem(path,[default value])``` to traverse the json tree and get the data.
68+
```php
69+
$json->getItem('openapi'); // 3.0.3
70+
$json->getItem('info.title'); // Swagger Petstore - OpenAPI 3.0
71+
$json->getItem('info.contact.email'); // [email protected]
72+
$json->getItem('servers.1.url'); // https://petstore3.swagger.io/api/v3
73+
```
74+
it can also return the rest of the json branches, for example
75+
```php
76+
$json->getItem('info.contact'); // stdClass {"email": "[email protected]"}
77+
```
78+
#### Handling path that doesn't exist
79+
if the path doesn't exist, the default value is returned which is either null (default) or anything you put on second parameter. It won't throw 'Undefined property' exception even if the whole path doesn't exist. So you can safely traverse without having to do check at every level.
80+
```php
81+
$json->getItem('info.contact.phone'); // null (path not found in tree, default to null)
82+
$json->getItem('info.contact.phone',1234); // 1234 (set the default to 1234 instead of null)
83+
$json->getItem('info.foo.bar',false); // false (doesn't throw 'Undefined property "foo"' exception)
84+
```
85+
### 3. Set a JSON data
86+
In order to set a data to the tree, you can use ```setItem(path,value)``` for example
87+
```php
88+
$json->setItem('info.version','1.0.0');
89+
```
90+
the json would become
91+
```json
92+
{
93+
"openapi": "3.0.3",
94+
"info": {
95+
"title": "Swagger Petstore - OpenAPI 3.0",
96+
"description": "This is a sample",
97+
"contact": {
98+
"email": "[email protected]"
99+
},
100+
"version": "1.0.0"
101+
},
102+
...
103+
```
104+
You can safely make new depth to the path
105+
```php
106+
$json->setItem('info.foo.bar.baz','somevalue');
107+
```
108+
```json
109+
{
110+
"openapi": "3.0.3",
111+
"info": {
112+
"foo": {
113+
"bar": {
114+
"baz": "somevalue"
115+
}
116+
},
117+
"title": "Swagger Petstore - OpenAPI 3.0",
118+
...
119+
```
120+
#### Setting Array
121+
For array data, you can explicitly use index, or use '[]' to change or append an element into either existing or new array.
122+
```php
123+
$json->setItem('servers.2.url', "new url");
124+
//or
125+
$json->setItem('servers.[].url', "new url");
126+
```
127+
will result in
128+
```json
129+
...
130+
"servers": [
131+
{
132+
"url": "https://petstore2.swagger.io/api/v2"
133+
},
134+
{
135+
"url": "https://petstore3.swagger.io/api/v3"
136+
},
137+
{
138+
"url": "new url"
139+
}
140+
],
141+
...
142+
```
143+
### 3. Get last valid path
144+
After executing ```getItem()```, you can use ```getLastValidPath()``` to retrieve the last valid path that was successfully traversed by the getItem method.
145+
```php
146+
$json->getItem('info.contact.phone.home');
147+
//will return "info.contact", because from 'phone' onward doesn't exist
148+
```
149+
### 4. Get the current full JSON object
150+
To get the current json as an object, use ```getJsonObject()```. Or alternatively the json-encoded string using ```getJsonString()```.
151+
### 5. Save json string to file
152+
To save the json string, use ```saveAs(file_path)```
153+
```php
154+
$json->saveAs(storage_path('/app/public/result.json'));
155+
```
156+
make sure that the directory is writable.

Diff for: composer.json

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "gemul/jsonparser",
3+
"description": "A PHP Library to easily handle JSON data",
4+
"type": "library",
5+
"keywords": [
6+
"json",
7+
"json-parser"
8+
],
9+
"require": {
10+
"php": "^7.0.1"
11+
},
12+
"autoload": {
13+
"psr-4": {
14+
"Gemul\\Jsonparser\\": "src/"
15+
}
16+
},
17+
"authors": [
18+
{
19+
"name": "Gema Ulama Putra",
20+
"email": "[email protected]",
21+
"homepage": "https://gemaulamaputra.id"
22+
}
23+
],
24+
"support": {
25+
"issues": "https://github.com/gemul/jsonparser/issues",
26+
"source": "https://github.com/gemul/jsonparser",
27+
"discussions": "https://github.com/gemul/jsonparser/discussions"
28+
},
29+
"license": "Apache-2.0",
30+
"minimum-stability": "dev"
31+
}

Diff for: src/JsonParser.php

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<?php
2+
namespace App\Custom;
3+
4+
class JsonParser {
5+
private $jsonObject;
6+
private $pathSeparator = '.';
7+
private $lastValidPath = null;
8+
9+
/**
10+
* JsonParser constructor.
11+
*
12+
* @param string $json The JSON string to parse or a file path to a JSON file.
13+
* @throws \Exception If the JSON string is invalid.
14+
*/
15+
16+
public function __construct(String $json, String $pathSeparator = '.') {
17+
try {
18+
$this->jsonObject = json_decode($json, false, 512, JSON_THROW_ON_ERROR);
19+
}catch(\JsonException $e) {
20+
//treat as file path
21+
try {
22+
if(!file_exists($json)) {
23+
throw new \Exception('Invalid JSON string or file path.');
24+
}
25+
$this->jsonObject = json_decode(file_get_contents($json));
26+
}catch(\Exception $e) {
27+
throw new \Exception('Invalid JSON string or file path not found.');
28+
}
29+
}
30+
$this->pathSeparator = $pathSeparator;
31+
}
32+
33+
/**
34+
* Gets the JSON object.
35+
*
36+
* @return object The JSON object.
37+
*/
38+
public function getJsonObject() {
39+
return $this->jsonObject;
40+
}
41+
42+
/**
43+
* Gets the JSON string representation of the JSON object.
44+
*
45+
* @param bool $pretty Whether to format the JSON string for readability.
46+
* @return string The JSON string representation of the JSON object.
47+
*/
48+
public function getJsonString(bool $pretty = false) {
49+
return json_encode($this->jsonObject, $pretty ? JSON_PRETTY_PRINT : 0);
50+
}
51+
52+
/**
53+
* Gets the value of an item in the JSON object at the specified path.
54+
*
55+
* @param string $path The path to the item in the JSON object.
56+
* @param mixed $default The default value to return if the item is not found.
57+
* @return mixed The value of the item at the specified path, or the default value if the item is not found.
58+
*/
59+
public function getItem(String $path, $default = null){
60+
$path = explode($this->pathSeparator, $path);
61+
$item = $this->jsonObject;
62+
$this->lastValidPath = "";
63+
foreach($path as $key){
64+
if(is_object($item) && !isset($item->$key)){
65+
return $default;
66+
} elseif(is_array($item) && !isset($item[$key])) {
67+
return $default;
68+
}
69+
$this->lastValidPath .= $this->lastValidPath=="" ? $key : $this->pathSeparator.$key;
70+
$item = is_object($item) ? $item->$key : $item[$key];
71+
}
72+
return $item;
73+
}
74+
75+
/**
76+
* Sets the value of an item in the JSON object at the specified path.
77+
*
78+
* @param string $path The path to the item in the JSON object.
79+
* @param mixed $value The value to set the item to.
80+
* @return void
81+
*/
82+
public function setItem(String $path, $value){
83+
$path = explode($this->pathSeparator, $path);
84+
$item = $this->jsonObject;
85+
$lastKey = array_pop($path);
86+
$traversedPath = [];
87+
for($i=0;$i<count($path);$i++){
88+
$traversedPath[] = $path[$i];
89+
$key = $path[$i];
90+
$nextKey = isset($path[$i+1]) ? $path[$i+1] : $lastKey;
91+
if(is_array($item)){
92+
if($key=="[]"){
93+
//get latest index
94+
end($item);
95+
$key = key($item)+1;
96+
}
97+
if(!isset($item[$key])){
98+
$item[$key] = is_numeric($nextKey) || $nextKey=="[]" ? [] : new \stdClass();
99+
}
100+
$item = &$item[$key];
101+
} elseif(is_object($item)){
102+
if(!isset($item->$key)){
103+
$item->$key = is_numeric($nextKey) || $nextKey=="[]" ? [] : new \stdClass();
104+
}
105+
$item = &$item->$key;
106+
}
107+
}
108+
if(is_array($item)){
109+
if($lastKey=="[]"){
110+
$item[] = $value;
111+
} else {
112+
$item[$lastKey] = $value;
113+
}
114+
} else {
115+
$item->$lastKey = $value;
116+
}
117+
}
118+
119+
/**
120+
* Saves the JSON object to a file at the specified path.
121+
*
122+
* @param string $path The path to save the JSON object to.
123+
* @return void
124+
*/
125+
public function saveAs(String $path){
126+
file_put_contents($path, $this->getJsonString());
127+
}
128+
129+
/**
130+
* Gets the last valid path that was successfully traversed by the getItem method.
131+
*
132+
* @return string The last valid path that was successfully traversed by the getItem method.
133+
*/
134+
public function getLastValidPath(){
135+
return $this->lastValidPath;
136+
}
137+
}

0 commit comments

Comments
 (0)