How can I decode a json database file that contains references to other json files using PHP? The goal is to get a single object with all references loaded.
Example of a json database file with references:
{
"id": 12,
"title": "Credit card number disclosure",
"severity": "medium",
"description": {
"$ref": "#/files/description/12"
},
"fix": {
"effort": 50,
"guidance": {
"$ref": "#/files/fix/57"
}
},
"cwe": [
"200"
],
"references": [
{
"url": "http://en.wikipedia.org/wiki/Luhn_algorithm",
"title": "Wikipedia - Luhn algorithm"
},
{
"url": "http://en.wikipedia.org/wiki/Bank_card_number",
"title": "Wikipedia - Bank card number"
}
]
}
file_get_contents() with a json_decode() will not automatically load the references.
<?PHP
$json_file = file_get_contents("db.json");
$json = json_decode($json_file);
function walkObject($obj) {
foreach($obj as $prop => $value) {
if (is_object($value))
$obj->$prop = walkObject($value);
if ($prop == "\$ref")
$obj->$prop = walkObject(json_decode(file_get_contents($value)));
}
return $obj;
}
This will load your initial json file, decode it and walk over it recursively. Every time it sees a $ref property - it will try to read the file it points to decode it and walk over it recursively...
You should implement checks for errors for file_get_contents and json_decode..
Related
I'm facing an error when trying to post JSON data into PHP. I am new at this.
any helps makes good for us
the JSON looks like this:
[
{
"sections": [
{
"section_id": "62",
"section_name": "English Language",
}
]
},
{
"questions": [
{
"section_id": "62",
"questionid": "1231",
},
{
"section_id": "62",
"questionid": "1232",
"time_spent": "0",
"status": "unseen",
"testsession_id": "whqgo41nsyurpi2"
},
{
"section_id": "62",
"questionid": "1233",
}
]
}
]
below is the code I wrote. Please correct the PHP code to access those JSON values.
$data = json_decode(file_get_contents("php://input"),true);
foreach ($data['sections'] as $value){
echo $value[section_id];
}
foreach ($data['questions'] as $value){
echo $value[section_id];
}
You are missing the array aspect of the JSON. The JSON is made up of an array firstly, which contains 2 objects, which have parameters of sections in the first, and questions in the second.
sections and questions are both arrays, which can be iterated over using foreach, which returns each of the elements as an object.
Your code after decoding the JSON should be like this.
foreach ($data[0]['sections'] as $value){
echo $value['section_id'];
}
foreach ($data[1]['questions'] as $value){
echo $value['section_id'];
}
My json file look likes
myjson.json
[
{"name":"category_01","data":
[
{"id":"1","word":"ma","given_value":"1"},
{"id":"3","word":"me","given_value":"1"},
] }
[
{"name":"category_02","data":
[
{"id":"1","word":"vea","given_value":"1"},
{"id":"3","word":"ve","given_value":"1"},
] }
So what I want here is, check whether a particular value is in this json array using php. Assume that,
myphp.php
$word = 've';
if this value is in the above array, should find is it in category_01 or category_02. and also want to find given_value of matching word.
I just tried in this way,
$data = file_get_contents ("myjson.json");
$json = json_decode($data, true);
foreach($arr as $item) {
$uses = ($item['word']= $word);
}
This doesn't work. How can I fix this, Please help me!
First of all, the JSON you posted is invalid. I think it should look like this:
[
{
"name": "category_01",
"data": [{
"id": "1",
"word": "ma",
"given_value": "1"
},
{
"id": "3",
"word": "me",
"given_value": "1"
}
]
},
{
"name": "category_02",
"data": [{
"id": "1",
"word": "vea",
"given_value": "1"
},
{
"id": "3",
"word": "ve",
"given_value": "1"
}
]
}
]
Try using on online tool like https://jsonlint.com/ to check your JSON. (if you get errors i recommend build the json again from scratch).
I also recommend checking your json before using it:
if ($arr === null && json_last_error() !== JSON_ERROR_NONE) {
die("incorrect json data");
}
To get your value you have to KNOW how your data looks like and then process it:
foreach($arr as $category) {
foreach($category['data'] as $data) {
if(strstr($data['word'], $word))
echo $category['name'].' '.$data['word'].' '.$data['given_value']."\n";
}
}
Assume that I have below json response fetched from an API.
{
"owner": "Jane Doe",
"pets": [
{
"color": "white",
"type": "cat"
},
{
"color": "black",
"type": "dog"
}
]
}
From the below PHP code I have converted the json string into a json object. And displayed the pet types.
$jsonObject = json_decode($json);
foreach($jsonObject->pets as $pets){
echo 'Pet type:'.$pets->type.'</br>';
}
However in some cases the response json from the API is in below format
{
"owner": "John Doe",
"pets": {
"color": "white",
"type": "cat"
}
}
in this case above php foreach iteration fails with below message
*Notice: Trying to get property of non-object *
I'm looking for a easy way to do this because the actual json response which i'm handling has lot of these occurrences.
You need to check whether $jsonObject->pets is an array or object. If it's an object, replace it with an array containing that object, then the loop will work.
if (!is_array($jsonObject->pets)) {
$jsonObject->pets = array($jsonObject->pets);
}
You could also do it with a conditional in the foreach:
foreach (is_array($jsonObject->pets) ? $jsonObject->pets : [jsonObject->pets] as $pet) {
...
}
If you don't want to have to write all that every time, you could put it in a function:
function as_array($x) {
return is_array($x) ? $x : [x];
}
and then use:
foreach (as_array($jsonObject->pets) as $pet) {
...
}
I'd also complain to the API designer. It's ridiculous to return inconsistent data formats like this.
I have the following deocoded JSON array.
I need to access the "type" inside the context, as well as I need to loop through each of the values in the payload. How do I do that?
{
"RequestHeader":
{
"mess": "am putting it on my wall....",
"created_time": "2010-08-24T09:01:25+0000"
},
"context" :
{
"type": "friends,circles"
}
"payload" [ {12345},{12345} ,{2345} ]
}
I tried the following, but it doesn't work
$decoded = json_decode($json_string);
for ($i=0;$i<payload.length;++$i)
{
$id=$decoded->payload[$i];
//do some operation with the id
}
First of all the JSON you provided is invalid. Supposedly the valid one should look like this
{
"RequestHeader": {
"mess": "am putting it on my wall....",
"created_time": "2010-08-24T09:01:25+0000"
},
"context": {
"type": "friends,circles"
},
"payload": [
12345,
12345,
2345
]
}
After you've fixed the problem with JSON provider it will be quite easy to access data
<?php
$json = <<<'JSON'
{
"RequestHeader": {
"mess": "am putting it on my wall....",
"created_time": "2010-08-24T09:01:25+0000"
},
"context": {
"type": "friends,circles"
},
"payload": [
12345,
12345,
2345
]
}
JSON;
$data = json_decode($json, true);
$type = $data['context']['type'];
var_dump($type);
foreach($data['payload'] as $id) {
var_dump($id);
}
Remember to make sure you check that the data actually exists before accessing it, e.g. isset($data['context']['type']) unless you are absolutely sure in it's integrity.
When you use json_decode method, the output will be nested arrays
So for example to access context type you need to do the following
echo $decoded["context"]["type"];
And to loop on payload you need to do the following
for ($i=0;$i<$decoded["payload"].length;++$i)
{
$id=$decoded["payload"][$i];
//do some operation with the id
}
I have a big JSON that looks something like this:
{
"bracers": [
{
"id": "Bracers_208",
"name": "Unearthed Boon"
}
],
"offHand": [
{
"id": "Bracers_208",
"name": "Unearthed Boon"
},
{
"id": "Weapon123",
"name": "Some Weapon Boon"
},
{
"id": "Weapon456",
"name": "Some Other Weapon Boon"
}
],
"mainHand": [
{
"id": "Weapon123",
"name": "Some Weapon Boon"
}
]
}
I decode the JSON like this:
$itemDB = json_decode($json, true);
What I want to do now is to remove all entries from offHand that are already in mainHand. So I loop through both, compare the id and unset() the value if there's a match.
foreach($itemDB['offHand'] as $index => $item) {
foreach($itemDB['mainHand'] as $key => $weapon) {
if($item['id'] == $weapon['id']) {
unset($itemDB['offHand'][$index]);
}
}
}
Then I encode it again:
$newJSON = json_encode($itemDB, JSON_PRETTY_PRINT);
The removal of duplicates works, but the offHand array is changed into an object (or assoc array) that looks like this:
{
"bracers": [
{
"id": "Bracers_208",
"name": "Unearthed Boon"
}
],
"offHand": [
"0": {
"id": "Bracers_208",
"name": "Unearthed Boon"
},
"2": {
"id": "Weapon456",
"name": "Some Other Weapon Boon"
}
],
"mainHand": [
{
"id": "Weapon123",
"name": "Some Weapon Boon"
}
]
}
Why does this happen and how can I prevent it?
Edit:
Just to clarify, if I remove the unset function and just do nothing inside that loops ( or just add a property to the objects), the numbered additional keys in the JSON aren't there and the JSON array is fine. That's why I concluded that unset is causing this.
After you're loop ends, add the following line of code to remove the keys from the offHand array element:
$itemDB['offHand'] = array_values($itemDB['offHand']);
As much a I think , by unset, you are removing a part of array, making it non sequential Thus it might be converted into object
I guess the above line was bit unclear, so consider this example,
function ep($f)
{
echo "<br><pre><code>";
print_r($f);
echo "</code></pre><br";
}
$t = array("a","b","c");
ep(json_encode($t));
unset($t[1]);
ep(json_encode($t));
Forget the function ep.On line 1 , we declare a sequential array and print it, as it is sequential it prints as an array. On line 2, we break the sequence. So printing it again , though it is an array, (*it maybe PHP's function does not know how to convert it) it printed as Object