PHP array to Json tree format - php

I want to tranform an php array into an json string to use with JavaScript InfoVis Toolkit formart.
the objective:
InfoVis Demo Tree
Json specification format:
InfoVis-loading and serving JSON data
I have this php array: $my_array :
Array
(
[item_1] => Array
(
[id] => item_1_ID
[name] => item_1_NAME
[data] => item_1_DATA
[children] => Array
(
[door] => Array
(
[id] => door_ID
[name] => door_NAME
[data] => door_DATA
[children] => Array
(
[mozart] => Array
(
[id] => mozart_ID
[name] => mozart_NAME
[data] => mozart_DATA
[children] => Array
(
[grass] => Array
(
[id] => grass_ID
[name] => grass_NAME
[data] => yes
)
[green] => Array
(
[id] => green_ID
[name] => green_NAME
[data] => no
)
[human] => Array
(
[id] => human_ID
[name] => human_NAME
[data] => human_DATA
[children] => Array
(
[blue] => Array
(
[id] => blue_ID
[name] => blue_NAME
[data] => blue_DATA
[children] => Array
(
[movie] => Array
(
[id] => movie_ID
[name] => movie_NAME
[data] => yes
)
)
)
)
)
)
)
)
)
[beat] => Array
(
[id] => beat_ID
[name] => beat_NAME
[data] => yes
)
[music] => Array
(
[id] => music_ID
[name] => music_NAME
[data] => no
)
)
)
)
now if I json_encode($my_array);
{
"item_1": {
"id": "item_1_ID",
"name": "item_1_NAME",
"data": "item_1_DATA",
"children": {
"door": {
"id": "door_ID",
"name": "door_NAME",
"data": "door_DATA",
"children": {
"mozart": {
"id": "mozart_ID",
"name": "mozart_NAME",
"data": "mozart_DATA",
"children": {
"grass": {
"id": "grass_ID",
"name": "grass_NAME",
"data": "yes"
},
"green": {
"id": "green_ID",
"name": "green_NAME",
"data": "no"
},
"human": {
"id": "human_ID",
"name": "human_NAME",
"data": "human_DATA",
"children": {
"blue": {
"id": "blue_ID",
"name": "blue_NAME",
"data": "blue_DATA",
"children": {
"movie": {
"id": "movie_ID",
"name": "movie_NAME",
"data": "yes"
}
}
}
}
}
}
}
}
},
"beat": {
"id": "beat_ID",
"name": "beat_NAME",
"data": "yes"
},
"music": {
"id": "music_ID",
"name": "music_NAME",
"data": "no"
}
}
}
}
But to InfoVis the current json output (json_encode($my_array)) has 3 problems:
is not using [ ]
the 'children' arrays have the key names
arrays items is with their key names -> example: "item_1": { ....
let me point the problem so maybe you can help with an function to transform this json string:
see this slice of json_encode($my_array) output:
{
"item_1": {
"id": "item_1_ID",
"name": "item_1_NAME",
"data": "item_1_DATA",
"children": {
"door": {
"id": "door_ID",
1. problem 1:
{
"item_1": {
we have to remove those keys like: "item_1":
2. problem 2:
"children": {
"door": {
"id": "door_ID",
the correct code for this should be:
"children": [
{
"id": "door_ID",......
"door": was removed... because it`s a key
"children": { => becomes" "children": [
An working example of 'children':
"children": [
{
"id": "grass_ID",
"name": "grass_NAME",
"data": "yes"
},
{
"id": "green_ID",
"name": "green_NAME",
"data": "no"
}
]
to clarify an complete example of WORKING Json InfoVis format:
json = {
id: "node02",
name: "0.2",
children: [{
id: "node13",
name: "1.3",
children: [{
id: "node24",
name: "2.4"
}, {
id: "node222",
name: "2.22"
}]
}, {
id: "node125",
name: "1.25",
children: [{
id: "node226",
name: "2.26"
}, {
id: "node237",
name: "2.37"
}, {
id: "node258",
name: "2.58"
}]
}, {
id: "node165",
name: "1.65",
children: [{
id: "node266",
name: "2.66"
}, {
id: "node283",
name: "2.83"
}, {
id: "node2104",
name: "2.104"
}, {
id: "node2109",
name: "2.109"
}, {
id: "node2125",
name: "2.125"
}]
}, {
id: "node1130",
name: "1.130",
children: [{
id: "node2131",
name: "2.131"
}, {
id: "node2138",
name: "2.138"
}]
}]
};
is it clear to understand?
Hope anyone can help me.. I'm working on this for days!
thank you.

Try this quickie conversion function
function fixit($yourArray) {
$myArray = array();
foreach ($yourArray as $itemKey => $itemObj) {
$item = array();
foreach ($itemObj as $key => $value) {
if (strtolower($key) == 'children') {
$item[$key] = fixit($value);
} else {
$item[$key] = $value;
}
}
$myArray[] = $item;
}
return $myArray;
}
$fixed = fixit($my_array);
$json = json_encode($fixed);

PHP doesn't differentiate between arrays (numeric keys) and associative arrays (string keys). They're all just Arrays. Javascript DOES differentiate. Since you're using string keys, they HAVE to be done as objects ({}) in JS.
You can't tell json_encode to ignore the keys in an array (e.g. your 'children' sub-arrays). That'd mean the produced JSON is NOT the same as the original PHP structure - you've now changed key names.
You'd have to process your array and convert all those children sub-array keys to numbers:
grass -> 0
green -> 1
etc...
so that json-encode could see that it's a numerically keyed PHP array, meaning it'll produce an actual javavscript array ([]), and not an object ({}).
The alternative is writing your own JSON-encoder to do this on-the-fly for you.

This is documented behaviour. An associative array will produce an object literal when JSON stringified with json_encode. Update your original array structure to represent the outcome you want, instead of mangling the produced JSON representation, or wrap your own solution around json_encode for each object.
Edit: attempting a cleanup operation
The code
$original = <your original data-array>; // assumed, I reversed your encoded JSON as test data
// Start by stripping out the associative keys for level 1
$clean = array_values($original);
// Then recursively descend array, and do the same for every children-property encountered
function &recursiveChildKeysCleaner(&$arr) {
// If $arr contains 'children'...
if (array_key_exists('children', $arr)) {
/// ...strip out associative keys
$arr['children'] = array_values($arr['children']);
// ...and descend each child
foreach ($arr['children'] as &$child) {
recursiveChildKeysCleaner($child);
}
}
return $arr;
}
foreach ($clean as &$item) {
recursiveChildKeysCleaner($item);
}
unset($item);
echo json_encode($clean);
Output
[{
"id": "item_1_ID",
"name": "item_1_NAME",
"data": "item_1_DATA",
"children": [{
"id": "door_ID",
"name": "door_NAME",
"data": "door_DATA",
"children": [{
"id": "mozart_ID",
"name": "mozart_NAME",
"data": "mozart_DATA",
"children": [{
"id": "grass_ID",
"name": "grass_NAME",
"data": "yes"
},
{
"id": "green_ID",
"name": "green_NAME",
"data": "no"
},
{
"id": "human_ID",
"name": "human_NAME",
"data": "human_DATA",
"children": [{
"id": "blue_ID",
"name": "blue_NAME",
"data": "blue_DATA",
"children": [{
"id": "movie_ID",
"name": "movie_NAME",
"data": "yes"
}]
}]
}]
}]
},
{
"id": "beat_ID",
"name": "beat_NAME",
"data": "yes"
},
{
"id": "music_ID",
"name": "music_NAME",
"data": "no"
}]
}]

Related

Sort a multidimensional array in PHP by a given value

I have the following structure:
{
"data": {
"array_1": [
{
"name": "Robert Kalani"
},
{
"name": "Balkan Boy",
}
],
"array_2": [
{
"name": "Pepe Dolan"
},
{
"name": "John Nolan",
}
],
"array_3": [
{
"name": "Phillip A. Luna",
},
{
"name": "Eugene Garcia"
}
]
}
}
I would like to sort each array by the name key in alpabetical order, not sure on how to do that, I've read about array_multisort but it seemed not to work. Would greatly appreciate some help
Here is the expected output
{
"data": {
"array_1": [
{
"name": "Balkan Boy",
},
{
"name": "Robert Kalani"
}
],
"array_2": [
{
"name": "John Nolan"
},
{
"name": "Pepe Dolan"
}
],
"array_3": [
{
"name": "Eugene Garcia"
},
{
"name": "Phillip A. Luna"
}
]
}
}
// Your JSON Data
$data = '{
"data": {
"array_1": [{ "name": "Robert Kalani" }, { "name": "Balkan Boy" }],
"array_2": [{ "name": "Pepe Dolan" }, { "name": "John Nolan" }],
"array_3": [{ "name": "Phillip A. Luna" }, { "name": "Eugene Garcia" }]
}
}
';
$result = [];
// Convert your JSON data to associative array
$array = json_decode($data, true)['data'];
function sort_by_name($a, $b)
{
return $a > $b;
}
foreach ($array as $item) {
uasort($item, "sort_by_name");
$result[] = $item;
}
echo "<pre>";
print_r($result);
Result:
Array
(
[0] => Array
(
[1] => Array
(
[name] => Balkan Boy
)
[0] => Array
(
[name] => Robert Kalani
)
)
[1] => Array
(
[1] => Array
(
[name] => John Nolan
)
[0] => Array
(
[name] => Pepe Dolan
)
)
[2] => Array
(
[1] => Array
(
[name] => Eugene Garcia
)
[0] => Array
(
[name] => Phillip A. Luna
)
)
)

Need to insert new key value pairs recursiverly inside every children json array

i have a nested json array of objects:
$json_url_data = [{
"form_name": "z1",
"name":"name1",
"children": [{
"form_name": "z2",
"name":"name2",
"children": [{
"form_name": "z3",
"name":"name2"
}]
}]
}]
i want to dynamically insert a new key value pair, which should look some thing like this:
[{
"form_name": "z1",
"name":"name1",
"peopleCount": "125,678,190",
"children": [{
"form_name": "z2",
"name":"name2",
"peopleCount": "156,987",
"children": [{
"form_name": "z3",
"name":"name2",
"peopleCount": "678,098"
}]
}]
}]
And i tried using recursion like below, but wasnt able to achieve the above result:
function print_data($menu, $depth) {
foreach ($menu as $value) {
$deepid = '\"'.$value['form_name'].'\"';
$api_call_var = '{{i have a apiu call proxy here}}';
$read_data = file_get_contents($read_data);
$read_data = json_decode($read_data, true);
$value['peopleCount'] = $read_data['count']; // after decode read the count
$obj_array[] = $value;
if (is_array($value['children'])) {
print_data ($value['children'],$depth+1);
}
}//end of for each
}//end of function
print_data ($json_url_data, 0);
i am stuck for hours, any help will be really appreciated.
This should solve your issue. When updating same array, you need to receive parameters as reference and update the same array in recursion.
Here is the code. I've added 123 as peopleCount but you add value using the API call.
<?php
echo "<pre>";
$json_url_data = json_decode('[{
"form_name": "z1",
"name":"name1",
"children": [{
"form_name": "z2",
"name":"name2",
"children": [{
"form_name": "z3",
"name":"name2"
}]
}]
}]', true);
function print_data(&$menu) {
foreach($menu as &$value) {
$value['peopleCount'] = 123; // using some API call add peopleCount value here
if(isset($value['children'])) {
print_data($value['children']);
}
}
return $menu;
}
print_r(print_data($json_url_data));
And this is the output.
Array
(
[0] => Array
(
[form_name] => z1
[name] => name1
[children] => Array
(
[0] => Array
(
[form_name] => z2
[name] => name2
[children] => Array
(
[0] => Array
(
[form_name] => z3
[name] => name2
[peopleCount] => 123
)
)
[peopleCount] => 123
)
)
[peopleCount] => 123
)
)
$arr = json_decode('[{
"form_name": "z1",
"name":"name1",
"peopleCount": "125,678,190",
"children": [{
"form_name": "z2",
"name":"name2",
"peopleCount": "156,987",
"children": [{
"form_name": "z3",
"name":"name2",
"peopleCount": "678,098"
}]
}]
}]', TRUE);
function countTotal($data) {
if(is_array($data)){
foreach($data as $row){
$row['peopleCount'] = 0;///here total val
if(isset($row['children']) {
countTotal($row['children']);
}
}
}
else {
$data['peopleCount'] = 0;//here total val
}
}
countTotal(&$arr);

How to parse JSON decoded by cURL on PHP

I 'm trying to make some pages with php and curl using REST API. I can connect application and get all values as JSON format with curl on PHP. But, I can not parse values what i want.
I used this PHP commands for decode json values ;
$data = json_decode($response, true);
print_r($data);
When I use this command i'm getting returning value like this ;
Array ( [links] => Array ( ) [content] => Array ( [0] => Array (
[#type] => ConsumerEnt [links] => Array ( [0] =>
Array ( [#type] => link [rel] => GET: Request [href] =>
http.....
) => Array ...etc
There are arrays inside arrays.. I could not find how to parse values i want. You can see values i want at following json codes;
Do you have any idea how it can be possible ?
Than
You can see Decoded JSON by http://json.parser.online.fr/
{
"links": [],
"content": [
{
"#type": "ConsumerEnt",
"links": [
{
"#type": "link",
"rel": "GET: Request",
"href": "https://ip/url"
},
{
"#type": "link",
"rel": "POST:Request",
"href": "https://ip/url"
}
],
"entitledOrg": [
{
"tRef": "local",
"tLabel": "local",
"sRef": "768882f2-cf89-4cc8-92b7",
"sLabel": "USsB01"
}
],
"citems": "a0221dfd-00f9-4019-95ed",
"name": "NAME I WANT TO GET",
"description": "Basic",
"isNoteworthy": false,
"dateCreated": "2016-09-25T11:44:02.698Z",
"lastUpdatedDate": "2016-09-25T12:46:45.474Z",
"iconId": "a0221dfd-00f9-4019-95ed-a74faeb2e1b2",
"catalogItemTypeRef": {
"id": "com.company",
"label": "Compo"
},
"serviceRef": {
"id": "7c92b9a5-9dd5-4819-9320-4127b1e3009d",
"label": "NAME I WANT TO GET"
},
"outputResourceRef": {
"id": "composition.type",
"label": "test"
}
},
{
"#type": "ConsumerEnti",
"links": [
{
"#type": "link",
"rel": "GET: Request",
"href": "https://ip/url"
},
{
"#type": "link",
"rel": "POST:Request",
"href": "https://ip/url"
}
],
"entitledOrg": [
{
"tRef": "local",
"tLabel": "local",
"sRef": "768882f2-cf89-4cc8-92b7",
"sLabel": "astDF1"
}
],
"catalogItemId": "89b43bcb-4b23-4fc0-af26-66bd5c6bd1bc",
"name": "NAME I WANT TO GET",
"description": "RASDhFASel",
"isNoteworthy": false,
"dateCreated": "2016-10-27T07:55:03.243Z",
"lastUpdatedDate": "2016-10-27T07:56:00.754Z",
"iconId": "compos.png",
"catalogItemTypeRef": {
"id": "com.company",
"label": "Compo"
},
"serviceRef": {
"id": "7c92b9a5-9dd5-4819-9320-4127b1e3009d",
"label": "NAME I WANT TO GET"
},
"outputResourceRef": {
"id": "composition",
"label": "Dep"
}
}
],
"metadata": {
"size": 20,
"totalElements": 2,
"totalPages": 1,
"number": 1,
"offset": 0
}
}
I guess i solved my issue like this ;
$data = json_decode($response, true);
print_r($data);
$j=count($data["content"]);
for ( $say=0 ; $say < $j ; $say++ )
{
print $data["content"][$say]["name"];
}
as a result i can list my products ;
Product1
Product2
Product3

How do I insert an element into a nested PHP Associative Array?

I have read lots of answers on SO, but I cannot figure out how to make them work with my problem.
This is what I have:
{
"name": "My Company LLC ->",
"children": [
{
"name": "District of the Stores",
"children": [
{
"name": "johnny1"
},
{
"name": "jonny2"
}
]
}, //I don't want my array to end here
{
"name": "store number 10",
"children": [
{
"name": "johnny3"
},
{
"name": "jonny4"
}
]
}
]
}
This is what I want.
{
"name": "My Company LLC ->",
"children": [
{
"name": "District of the Stores",
"children": [
{
"name": "johnny1"
},
{
"name": "jonny2"
},
{
"name": "store number 10",
"children": [
{
"name": "johnny3"
},
{
"name": "jonny4"
}
]
}
]
}
]
}
Here is what I tried to do it with:
$name=array('name'=>'My Company LLC ->');
$name['children']=array(array('name'=>'District of the Stores', 'children'=>array(array('name'=>'johnny1'), array('name'=>'jonny2'))));
$name['children'][]=array('name'=>'store number 10', 'children'=>array(array('name'=>'johnny3'), array('name'=>'jonny4')));
echo '<pre>';
echo json_encode($name, JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK);
echo '</pre>';
I know that I am inserting an array at the end of the children array which is causing my second array problem in the first example, but I don't know how to put the second children array back into the first one back in the original. This is part of a big list from a database, but I'm stuck here. I cannot see where the SO answers I've found help me to insert the second array.
It looks like you want this:
$name['children'][0]['children'][] = array(...);
This would reference the first child of the root element (index 0), then proceed like you did previously by adding to that elements children array.
$name=array('name'=>'My Company LLC ->');
$name['children']=array(array('name'=>'District of the Stores', 'children'=>array(array('name'=>'johnny1'), array('name'=>'jonny2'), array('name'=>'store number 10', 'children'=>array(array('name'=>'johnny3'), array('name'=>'johnny4'))))));
echo '<pre>';
echo json_encode($name, JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK);
echo '</pre>';
Here is the output
{
"name": "My Company LLC ->",
"children": [
{
"name": "District of the Stores",
"children": [
{
"name": "johnny1"
},
{
"name": "jonny2"
},
{
"name": "store number 10",
"children": [
{
"name": "johnny3"
},
{
"name": "johnny4"
}
]
}
]
}
]
}
If you want to keep the lines of code separate you can do the following:
$name=array('name'=>'My Company LLC ->');
$name['children']=array(array('name'=>'District of the Stores', 'children'=>array(array('name'=>'johnny1'), array('name'=>'jonny2'))));
$name['children'][0]['children'][] = array('name'=>'store number 10', 'children'=>array(array('name'=>'johnny3'), array('name'=>'johnny4')));
echo '<pre>';
echo json_encode($name, JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK);
echo '</pre>';
Also, it is probably a lot easier to debug this sort of thing by looking at the array instead of encoding into json. here is your original output as an array, which really shows you what's going on better.
$name=array('name'=>'My Company LLC ->');
$name['children']=array(array('name'=>'District of the Stores', 'children'=>array(array('name'=>'johnny1'), array('name'=>'jonny2'))));
$name['children'][]=array('name'=>'store number 10', 'children'=>array(array('name'=>'johnny3'), array('name'=>'jonny4')));
echo '<pre>';
print_r($name);
echo '</pre>';
And the output is:
Array
(
[name] => My Company LLC ->
[children] => Array
(
[0] => Array
(
[name] => District of the Stores
[children] => Array
(
[0] => Array
(
[name] => johnny1
)
[1] => Array
(
[name] => jonny2
)
)
)
[1] => Array
(
[name] => store number 10
[children] => Array
(
[0] => Array
(
[name] => johnny3
)
[1] => Array
(
[name] => jonny4
)
)
)
)
)

Add new key/value pair into JSON in PHP

I have a result from my MySQL DB that I'm json encoding in PHP, the result looks like
:
[
{
"id": "8488",
"name": "Tenby",
"area": "Area1"
},
{
"id": "8489",
"name": "Harbour",
"area": "Area1"
},
{
"id": "8490",
"name": "Mobius",
"area": "Area1"
}
]
What I would like to do is to add a new key/value pair to that JSON so that it will be :
[
{
"id": "8488",
"name": "Tenby",
"area": "Area1",
"image": "1278.jpg"
},
{
"id": "8489",
"name": "Harbour",
"area": "Area1",
"image": "1279.jpg"
},
{
"id": "8490",
"name": "Mobius",
"area": "Area1",
"image": "1280.jpg"
}
]
So how can I do that in PHP?
<?php
$data[0]['id']="8488";
$data[0]['name']="Tenby";
$data[0]['area']="Area1";
$data[1]['id']="8489";
$data[1]['name']="Harbour";
$data[1]['area']="Area1";
$data[2]['id']="8490";
$data[2]['name']="Mobius";
$data[2]['area']="Area1";
echo json_encode($data)."<br/>";
/*Add Image element (or whatever) into the array according to your needs*/
$data[0]['image']="1278.jpg";
$data[1]['image']="1279.jpg";
$data[2]['image']="1280.jpg";
echo json_encode($data);
?>
PHP is not very good with JSON. Its best to convert from JSON to Array to do this - what #egig has also recommended.
Example code:
$temp = json_decode($json);
$temp[] = new data, whatever you want to add...;
$json = json_encode($temp);
Hope this helps.
hu?
the result of the db query will be an array or an object...
add the additional entry to that data, only encode after every necessary data manipulation is done
alternatives, but clumsy (horrible):
json_decode, add stuff, json_encode
build your additional data as a string, str_replace for example "area": "Area1" in your json string with "area": "Area1", "image": "1278.jpg"
but really:
output formatting like json_encode should only be done once you are sure that you have the whole output together and it is send out
Maybe things have changed since then, but I know this will work at this current stage:-
So here is the JSON string:-
$strJSON = '[
{
"id": "8488",
"name": "Tenby",
"area": "Area1"
},
{
"id": "8489",
"name": "Harbour",
"area": "Area1"
},
{
"id": "8490",
"name": "Mobius",
"area": "Area1"
}
]';
If this is still a string, then I would convert it into an object like this:-
$json = json_decode( $strJSON );
Now that it is in object format, to add my "image" keys with their values, I would then add them like it is shown below:-
$json[0]->image = "1278.jpg";
$json[1]->image = "1279.jpg";
$json[2]->image = "1280.jpg";
So then if I add the code below after the above code:-
echo "<pre>";
print_r( $json );
echo "</pre>";
We should then see it outputting on the page like so:-
Array
(
[0] => stdClass Object
(
[id] => 8488
[name] => Tenby
[area] => Area1
[image] => 1278.jpg
)
[1] => stdClass Object
(
[id] => 8489
[name] => Harbour
[area] => Area1
[image] => 1279.jpg
)
[2] => stdClass Object
(
[id] => 8490
[name] => Mobius
[area] => Area1
[image] => 1280.jpg
)
)
//$index = some value in array;
for($i=0;$i<count($index);$i++){
$data[$i]->key = $index[$i];
}
print $data;

Categories