Extracting hierachy structure into json - php

i am having trouble getting my mysql table into json.
I have a table that show the hierachy of employees like that:
The table is a employee table with
id, firstname, lastname, parentid
So now I want to query through the data to extract it into a multi level json object to simulate show the employees with their supervisors.
I hope somebody can help me with it.

Assuming you've already taken data from the database, below solution will get you what you need.
The way to go about it is via recursion.
php sandbox online
<?php
function buildTree(array &$elements, $parentId = 0) {
$branch = array();
foreach ($elements as $element) {
if ($element['parentid'] == $parentId) {
// recursion:
$children = buildTree($elements, $element['id']);
if ($children) {
$element['children'] = $children;
}
$branch[$element['id']] = $element;
unset($elements[$element['id']]);
}
}
return $branch;
}
$rows = [
['id' => 1, 'firstname' => 'john1', 'lastname' => 'doe', 'parentid' => 0],
['id' => 2, 'firstname' => 'john2', 'lastname' => 'doe', 'parentid' => 1],
['id' => 3, 'firstname' => 'john3', 'lastname' => 'doe', 'parentid' => 1],
['id' => 4, 'firstname' => 'john4', 'lastname' => 'doe', 'parentid' => 0],
['id' => 5, 'firstname' => 'john5', 'lastname' => 'doe', 'parentid' => 3],
];
print_r(buildTree($rows));
and the resulting array:
Array
(
[1] => Array
(
[id] => 1
[firstname] => john1
[lastname] => doe
[parentid] => 0
[children] => Array
(
[2] => Array
(
[id] => 2
[firstname] => john2
[lastname] => doe
[parentid] => 1
)
[3] => Array
(
[id] => 3
[firstname] => john3
[lastname] => doe
[parentid] => 1
[children] => Array
(
[5] => Array
(
[id] => 5
[firstname] => john5
[lastname] => doe
[parentid] => 3
)
)
)
)
)
[4] => Array
(
[id] => 4
[firstname] => john4
[lastname] => doe
[parentid] => 0
)
)
After you json_encode the result, you will get:
{
"1": {
"id": 1,
"firstname": "john1",
"lastname": "doe",
"parentid": 0,
"children": {
"2": {
"id": 2,
"firstname": "john2",
"lastname": "doe",
"parentid": 1
},
"3": {
"id": 3,
"firstname": "john3",
"lastname": "doe",
"parentid": 1,
"children": {
"5": {
"id": 5,
"firstname": "john5",
"lastname": "doe",
"parentid": 3
}
}
}
}
},
"4": {
"id": 4,
"firstname": "john4",
"lastname": "doe",
"parentid": 0
}
}

Related

function to make Tree like Array in to Array

I have $tree like array which made by function from the $array I need a function to make it $tree to $array back
so I need a function to make it back.
lets call it $list this time.
I will share $tree , $array and the function in below
tree like array ;
Array
(
[0] => Array
(
[id] => 1
[name] => id1
[children] => Array
(
[0] => Array
(
[id] => 2
[parent_id] => 1
[name] => id2
[children] => Array
(
[0] => Array
(
[id] => 5
[parent_id] => 2
[name] => id5
)
)
)
[1] => Array
(
[id] => 3
[parent_id] => 1
[name] => id3
[children] => Array
(
[0] => Array
(
[id] => 6
[parent_id] => 3
[name] => id6
)
[1] => Array
(
[id] => 8
[parent_id] => 3
[name] => id8
)
)
)
)
)
[1] => Array
(
[id] => 4
[name] => id4
[children] => Array
(
[0] => Array
(
[id] => 9
[parent_id] => 4
[name] => id9
[children] => Array
(
[0] => Array
(
[id] => 10
[parent_id] => 9
[name] => id10
)
)
)
)
)
[2] => Array
(
[id] => 7
[name] => id7
[children] => Array
(
)
)
)
Which made by a function from this array
$array = [
['id'=> 1, 'parent_id' => 0, 'name' => 'id1'],
['id' => 2, 'parent_id' => 1, 'name'=> 'id2'],
['id' => 3, 'parent_id' => 1, 'name'=> 'id3'],
['id' => 4, 'parent_id' => 0, 'name'=> 'id4'],
['id' => 5,'parent_id' => 2, 'name'=> 'id5'],
['id' => 6, 'parent_id' => 3, 'name'=> 'id6'],
['id' => 7, 'parent_id' => 0, 'name'=> 'id7'],
['id' => 8, 'parent_id' => 3, 'name'=> 'id8'],
['id' => 9, 'parent_id' => 4, 'name'=> 'id9'],
['id' => 10, 'parent_id' => 9, 'name'=> 'id10'],
];
function(making $array in to $tree)
$tree = [];
function buildTree (array $infos, int $parent_Id = null): array
{
$branch = [];
foreach ($infos as $info)
if($info['parent_id'] === $parent_Id){
$children = buildTree($infos , $info['id']);
if ($children){
$info['children'] = $children;
}
$branch[] = $info;
}
return $branch;
}
foreach ($array as $info){
if($info['parent_id']=== 0){
$tree[] = [
'id' => $info['id'],
'name' => $info['name'],
'children' => buildTree($array , $info['id']),
];
}
}
print_r($tree);
any explanation would be appreciated.
Result of this code can be found here: http://sandbox.onlinephpfunctions.com/code/38a091db5ace63900fa0bf69ddde17412118513c
function flatMergeArray(array $array, int $parentId = 0, array &$result = []): array
{
$subResult = [];
foreach ($array as $key => $sub) {
$parentId = $array['parent_id'] ?? 0;
if (is_array($sub)) {
flatMergeArray($sub, $parentId, $result);
} else {
$subResult[$key] = $sub;
}
}
if (!empty($subResult)) {
if (!isset($subResult['parent_id'])) {
$subResult['parent_id'] = 0;
}
$result[] = $subResult;
}
return $result;
}
function flatTree(array $tree): array
{
$array = flatMergeArray($tree);
usort($array, static function (array $node1, array $node2) {
return ($node1['id'] < $node2['id']) ? -1 : 1;
});
return array_values($array);
}
$tree = [
[
"id" => 1,
"name" => "id1",
"children" => [
[
"id" => 2,
"parent_id" => 1,
"name" => "id2",
"children" => [
[
"id" => 5,
"parent_id" => 2,
"name" => "id5"
]
]
],
[
"id" => 3,
"parent_id" => 1,
"name" => "id3",
"children" => [
[
"id" => 6,
"parent_id" => 3,
"name" => "id6"
],
[
"id" => 8,
"parent_id" => 3,
"name" => "id8"
]
]
]
]
],
[
"id" => 4,
"name" => "id4",
"children" => [
[
"id" => 9,
"parent_id" => 4,
"name" => "id9",
"children" => [
[
"id" => 10,
"parent_id" => 9,
"name" => "id10"
]
]
]
]
],
[
"id" => 7,
"name" => "id7",
"children" => [
]
]
];
$array = flatTree($tree);
print_r($array);

Search associative array for specific value based on set variable

I'm retrieving some JSON that I am converting to an associative array. The issue that I am having is I am trying to get the email value from the user's who id matches the value that I have already set as a variable.
Here is what the array looks like
Array
(
[object] => list
[data] => Array
(
[0] => Array
(
[object] => pro
[id] => pro_77c9c6a85d814e059a6a2690989bae29
[first_name] => Jane
[last_name] => Doe
[full_name] => Jane Doe
[initials] => JD
[email] => admin#testorg.com
[mobile_number] => 9998761234
[messaging_uuid] => 4547c231c3e7d0ff1796f47b88f166d5
[color_hex] => EF9159
[avatar_url] => /assets/add_image.png
[avatar_thumb_url] =>
[has_avatar] =>
[organization_name] => testorg
[is_admin] => 1
[permissions] => Array
(
[show_company_setup] => 1
[can_see_home_data] => 1
[show_reporting] => 1
)
[is_super_pro] =>
[is_archived] =>
[impersonated] =>
)
[1] => Array
(
[object] => pro
[id] => pro_0fcb8e8610e54c518078db77ced7530e
[first_name] => Robert
[last_name] => Jordan
[full_name] => Robert Jordan
[initials] => RJ
[email] => rj#testorg.com
[mobile_number] => 4547457742
[messaging_uuid] => 0fcb8e8610e54c518078db77ced7530e
[color_hex] => EF9159
[avatar_url] => /assets/add_image.png
[avatar_thumb_url] =>
[has_avatar] =>
[organization_name] => testorg
[is_admin] => 1
[permissions] => Array
(
[show_company_setup] => 1
[can_see_home_data] => 1
[show_reporting] => 1
)
[is_super_pro] =>
[is_archived] =>
[impersonated] =>
)
)
[url] => /pros
)
Im basically trying to match the value that I have set in my pro_id variable
pro_0fcb8e8610e54c518078db77ced7530e
To the 'ID' Key in the array above and get the 'email' value associated to that same array and store for use later in my code.
Here is what I have so far, but no joy
foreach ($proObject as $key => $value) {
if ($key['id'] == $pro_id)
$techmail = $key['email'];
}
From my understanding of your question, and if you want to get only one element, you should be able to use array_search with array_column to get the index of the searched element. Using that you can then access the element and its corresponding email value. If you might expect more than one element I would use array_filter.
One Element:
In short:
$i = array_search($pro_id, array_column($proObject, 'id'));
$element = ($i !== false ? $proObject[$i] : null);
print_r($element["email"]);
Full code:
<?php
$proObject = array(
array(
"object" => "pro",
"id" => "pro_77c9c6a85d814e059a6a2690989bae29",
"first_name" => "Jane",
"last_name" => "Doe",
"full_name" => "Jane Doe",
"initials" => "JD",
"email" => "admin#testorg.com",
"mobile_number" => "9998761234",
"messaging_uuid" => "4547c231c3e7d0ff1796f47b88f166d5",
"color_hex" => "EF9159",
"avatar_url" => "/assets/add_image.png",
"avatar_thumb_url" => "",
"has_avatar" => "",
"organization_name" => "testorg",
"is_admin" => "1",
"permissions" => array(
"show_company_setup" => "1",
"can_see_home_data" => "1",
"show_reporting" => "1",
) ,
"is_super_pro" => "",
"is_archived" => "",
"impersonated" => "",
) ,
array(
"object" => "pro",
"id" => "pro_0fcb8e8610e54c518078db77ced7530e",
"first_name" => "Robert",
"last_name" => "Jordan",
"full_name" => "Robert Jordan",
"initials" => "RJ",
"email" => "rj#testorg.com",
"mobile_number" => "4547457742",
"messaging_uuid" => "0fcb8e8610e54c518078db77ced7530e",
"color_hex" => "EF9159",
"avatar_url" => "/assets/add_image.png",
"avatar_thumb_url" => "",
"has_avatar" => "",
"organization_name" => "testorg",
"is_admin" => "1",
"permissions" => array(
"show_company_setup" => "1",
"can_see_home_data" => "1",
"show_reporting" => "1",
) ,
"is_super_pro" => "",
"is_archived" => "",
"impersonated" => "",
)
);
$pro_id = "pro_0fcb8e8610e54c518078db77ced7530e";
$i = array_search($pro_id, array_column($proObject, 'id'));
$element = ($i !== false ? $proObject[$i] : null);
print_r($element["email"]);
?>
Multiple Elements:
In short:
class idEqualsFilter {
private $id;
public function __construct($id) {
$this->id = $id;
}
function __invoke($i) {
return $this->id === $i["id"];
}
};
$elements = array_filter($proObject, new idEqualsFilter($pro_id));
print_r(array_column($elements, "email"));
Full code:
<?php
$proObject = array(
array(
"object" => "pro",
"id" => "pro_77c9c6a85d814e059a6a2690989bae29",
"first_name" => "Jane",
"last_name" => "Doe",
"full_name" => "Jane Doe",
"initials" => "JD",
"email" => "admin#testorg.com",
"mobile_number" => "9998761234",
"messaging_uuid" => "4547c231c3e7d0ff1796f47b88f166d5",
"color_hex" => "EF9159",
"avatar_url" => "/assets/add_image.png",
"avatar_thumb_url" => "",
"has_avatar" => "",
"organization_name" => "testorg",
"is_admin" => "1",
"permissions" => array
(
"show_company_setup" => "1",
"can_see_home_data" => "1",
"show_reporting" => "1",
),
"is_super_pro" => "",
"is_archived" => "",
"impersonated" => "",
),
array(
"object" => "pro",
"id" => "pro_0fcb8e8610e54c518078db77ced7530e",
"first_name" => "Robert",
"last_name" => "Jordan",
"full_name" => "Robert Jordan",
"initials" => "RJ",
"email" => "rj#testorg.com",
"mobile_number" => "4547457742",
"messaging_uuid" => "0fcb8e8610e54c518078db77ced7530e",
"color_hex" => "EF9159",
"avatar_url" => "/assets/add_image.png",
"avatar_thumb_url" => "",
"has_avatar" => "",
"organization_name" => "testorg",
"is_admin" => "1",
"permissions" => array
(
"show_company_setup" => "1",
"can_see_home_data" => "1",
"show_reporting" => "1",
),
"is_super_pro" => "",
"is_archived" => "",
"impersonated" => "",
)
);
$pro_id = "pro_0fcb8e8610e54c518078db77ced7530e";
class idEqualsFilter {
private $id;
public function __construct($id) {
$this->id = $id;
}
function __invoke($i) {
return $this->id === $i["id"];
}
};
$elements = array_filter($proObject, new idEqualsFilter($pro_id));
print_r(array_column($elements, "email"));
?>

How to restructure an array so that a sub array key becomes array key

First time posting here and really need some help. Relatively new to php I have an array that I'd like to restructure. I have subjects at top level with students in a sub array. I'd like to restructure so that Students are at the top level with subjects in a sub array.
$startingArray = [
[ "subject" => "Physics",
"student" => [
["id" => "00003", "Name" => "Peter", "email" => "peter#schooool.com",],
["id" => "00004", "Name" => "Mary", "email" => "mary#schooool.com",],
["id" => "00005", "Name" => "Jane", "email" => "jane#schooool.com",],
]
],
[ "subject" => "Chemistry",
"student" => [
["id" => "00003", "Name" => "Peter", "email" => "peter#schooool.com",],
["id" => "00004", "Name" => "Mary", "email" => "mary#schooool.com",],
["id" => "00005", "Name" => "Jane", "email" => "jane#schooool.com",],
]
],
[ "subject" => "Mathematics",
"student" => [
["id" => "00003", "Name" => "Peter", "email" => "peter#schooool.com",],
["id" => "00006", "Name" => "Fred", "email" => "fred#schooool.com",],
["id" => "00007", "Name" => "Wilma", "email" => "wilma#schooool.com",],
]
],
[ "subject" => "Biology",
"student" => [
["id" => "00004", "Name" => "Mary", "email" => "mary#schooool.com",],
["id" => "00006", "Name" => "Fred", "email" => "fred#schooool.com",],
["id" => "00008", "Name" => "Alison", "email" => "alison#schooool.com",],
]
]
];
I want my new array to be like this;
$endingArray = [
"students" => [
[ "id" => "00003",
"Name" => "Peter",
"email" => "peter#schooool.com",
"subjects" => [ "Physics", "Chemistry", "Mathematics", ],
],
[ "id" => "00004",
"Name" => "Mary",
"email" => "mary#schooool.com",
"subjects" => [ "Physics", "Chemistry", "Biology", ],
],
[ "id" => "00005",
"Name" => "Jane",
"email" => "jane#schooool.com",
"subjects" => [ "Physics", "Chemistry", ],
],
[ "id" => "00006",
"Name" => "Fred",
"email" => "fred#schooool.com",
"subjects" => [ "Mathematics", "Biology", ],
],
[ "id" => "00007",
"Name" => "Wilma",
"email" => "wilma#schooool.com",
"subjects" => [ "Mathematics", "Biology", ],
],
[ "id" => "00008",
"Name" => "Alison",
"email" => "alison#schooool.com",
"subjects" => [ "Physics", "Biology", ],
],
],
];
I'm trying a 2 stage process. First is to create the new students array without the subjects. This works fine.
Then I'm trying to append the subjects but I know my logic is wrong and the code I have just creates a new row for each student and each subject.
foreach ( $startingArray as $row ) {
$students = $row['student'];
foreach ($students as $student) {
if (!in_array($student, $studentsArray)) {
$studentsArray[] = $student;
}
}
}
the second step just produces garbage
$s1 = $student['id'];
foreach ($startingArray as $row) {
$subject = $row['subject'];
$students = $row['student'];
foreach ($students as $s2) {
if ($s2['id]'] = $s1) {
$student['subjects'] = $subject;
array_push($studentsArray, $student);
}
}
}
}
Any help appreciated!
Here what you can do:
$newArray = [];
foreach ($startingArray as $item) {
foreach ($item['student'] as $student) {
if (empty($newArray[$student['id']])) {
$student['subjects'] = [];
$newArray[$student['id']] = $student;
}
$newArray[$student['id']]['subjects'][] = $item['subject'];
}
}
Sample fiddle here.
Case you need to maintain a sequential id like your example do this
$newArray = [];
foreach ($startingArray as $item) {
foreach ($item["student"] as $student) {
$filter = array_filter($newArray, function ($d) use ($student) {
return ($d["id"] == $student["id"]);
});
if (!$filter) {
$student["subjects"][] = $item['subject'];
$newArray[] = $student;
} else {
$newArray[key($filter)]["subjects"][] = $item["subject"];
}
}
}
$finalArray = [
'students' => $newArray
];
The final result will be
Array
(
[students] => Array
(
[0] => Array
(
[id] => 00003
[Name] => Peter
[email] => peter#schooool.com
[subjects] => Array
(
[0] => Physics
[1] => Chemistry
[2] => Mathematics
)
)
[1] => Array
(
[id] => 00004
[Name] => Mary
[email] => mary#schooool.com
[subjects] => Array
(
[0] => Physics
[1] => Chemistry
[2] => Biology
)
)
[2] => Array
(
[id] => 00005
[Name] => Jane
[email] => jane#schooool.com
[subjects] => Array
(
[0] => Physics
[1] => Chemistry
)
)
[3] => Array
(
[id] => 00006
[Name] => Fred
[email] => fred#schooool.com
[subjects] => Array
(
[0] => Mathematics
[1] => Biology
)
)
[4] => Array
(
[id] => 00007
[Name] => Wilma
[email] => wilma#schooool.com
[subjects] => Array
(
[0] => Mathematics
)
)
[5] => Array
(
[id] => 00008
[Name] => Alison
[email] => alison#schooool.com
[subjects] => Array
(
[0] => Biology
)
)
)
)

How to create tree view hierarchy in php codeigniter?

I have a array like this :
Array
(
[0] => Array
(
[id] => 1
[child_name] => "Emma"
[parent_name] => "Mr Brown"
)
[1] => Array
(
[id] => 2
[child_name] => "John"
[parent_name] => "Mr Brown"
)
[2] => Array
(
[id] => 3
[child_name] => "Joseph"
[parent_name] => "Mr Thomas"
)
[3] => Array
(
[id] => 4
[child_name] => "Pretty"
[parent_name] => "Mr Thomas"
)
[4] => Array
(
[id] => 5
[child_name] => "Raphel"
[parent_name] => "Mr Brown"
)
[5] => Array
(
[id] => 6
[child_name] => "Tommy"
[parent_name] => "Mr Thomas"
)
[6] => Array
(
[id] => 7
[child_name] => "Tim"
[parent_name] => "Mr Thomas"
)
)
From this array I want to generate a view like this :
The parent_name field becomes the MainCategory and the child_name becomes the subcategory. The names have checkboxes in front of them.
How do I achieve this? I don't have much experience in php. I code in node js but this task needs this to be done in php.
How do I do this?
Try this, Here i use simple index() method and pass data to view file as an example.
You can use below code and test in your codeigniter.
Hope this will work for you.
Welcome.php (Controller)
public function index()
{
$array = [
[
'id' => 1,
'child_name' => "Emma",
'parent_name' => "Mr Brown",
],
[
'id' => 2,
'child_name' => "John",
'parent_name' => "Mr Brown",
],
[
'id' => 3,
'child_name' => "Joseph",
'parent_name' => "Mr Thomas",
],
[
'id' => 4,
'child_name' => "Pretty",
'parent_name' => "Mr Thomas",
],
[
'id' => 5,
'child_name' => "Raphel",
'parent_name' => "Mr Brown",
],
[
'id' => 6,
'child_name' => "Tommy",
'parent_name' => "Mr Thomas",
],
[
'id' => 7,
'child_name' => "Tim",
'parent_name' => "Mr Thomas",
],
[
'id' => 8,
'child_name' => "William",
'parent_name' => "",
],
];
$resultArray = [];
foreach ($array as $key => $value) {
if($value['parent_name'] != ''){
$resultArray[$value['parent_name']][] = $value;
}else{
$resultArray[$value['child_name']] = [];
}
}
$data = ['resultArray' => $resultArray];
$this->load->view('welcome_message', $data);
}
welcome_message.php (view)
<div>
<form name='sample'>
<?php
foreach ($resultArray as $parentKey => $parentValue) {
echo '<input type="checkbox" name="'.$parentKey.'" value="'.$parentKey.'">'.$parentKey.'<br>';
foreach ($parentValue as $childKey => $childValue) {
echo ' <input type="checkbox" name="'.$childValue['child_name'].'" value="'.$childValue['child_name'].'">'.$childValue['child_name'].'<br>';
}
}
?>
</form>
</div>
Output
Check this,
Loop your array, it will capture all values with same parent_name.
$result = [];
foreach ($array as $key => $value) {
$result[$value['parent_name']][] = $value['child_name']; // loop your array
}
It should work.

PHP id/parent, how to show all records

I found sample PHP code for creating JSON based on id<->parent and it looks like:
<?php
$rows = array(
array('id' => 1, 'parent' => 0, 'name' => 'John Doe'),
array('id' => 2, 'parent' => 1, 'name' => 'Sally Smith'),
array('id' => 3, 'parent' => 2, 'name' => 'Mike Jones'),
array('id' => 4, 'parent' => 3, 'name' => 'Jason Williams'),
array('id' => 5, 'parent' => 4, 'name' => 'Sara Johnson'),
array('id' => 6, 'parent' => 1, 'name' => 'Dave Wilson'),
array('id' => 7, 'parent' => 2, 'name' => 'Amy Martin'),
);
// create an index on id
$index = array();
foreach($rows as $row){
$row['data'] = (object) [];
$index[$row['id']] = $row;
}
// build the tree
foreach($index as $id => &$row){
if ($id === 0) continue;
$parent = $row['parent'];
$index[$parent]['children'][] = &$row;
}
unset($row);
// obtain root node
$index = $index[0]['children'][0];
// output json
header('Content-Type: application/json');
echo json_encode($index, JSON_PRETTY_PRINT);
it works fine but how to display all children records for specific ID? For example, I need all members for parent 2 so I try:
$index = $index[2]['children'][0];
and it display only 3 records and it should display 4 of them (Amy Martin is missing).
Thank you.
It is because you are trying to get 0 index so only 1st hierarchy will be displayed. To access all children remove [0] from your data
It should be:
$index = $index[2]['children'];
You only get 3 records because your 'children' are nested on different levels (the 4th one is on a different level
Array
(
[0] => Array
(
[id] => 3
[parent] => 2
[name] => Mike Jones
...
[children] => Array
(
[0] => Array
(
[id] => 4
[parent] => 3
[name] => Jason Williams
[children] => Array
(
[0] => Array
(
[id] => 5
[parent] => 4
[name] => Sara Johnson
...
)
)
)
)
)
[1] => Array
(
[id] => 7
[parent] => 2
[name] => Amy Martin
...
)
)
In order to get all the children you need to traverse and flatten your array. This can be done using an interator.
Full code sample:
<?php
$rows = array(
array('id' => 1, 'parent' => 0, 'name' => 'John Doe'),
array('id' => 2, 'parent' => 1, 'name' => 'Sally Smith'),
array('id' => 3, 'parent' => 2, 'name' => 'Mike Jones'),
array('id' => 4, 'parent' => 3, 'name' => 'Jason Williams'),
array('id' => 5, 'parent' => 4, 'name' => 'Sara Johnson'),
array('id' => 6, 'parent' => 1, 'name' => 'Dave Wilson'),
array('id' => 7, 'parent' => 2, 'name' => 'Amy Martin'),
);
// create an index on id
$index = array();
foreach($rows as $row){
$row['data'] = (object) [];
$index[$row['id']] = $row;
}
// build the tree
foreach($index as $id => &$row){
if ($id === 0) continue;
$parent = $row['parent'];
$index[$parent]['children'][] = &$row;
}
unset($row);
$array = $index[2]['children'];
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$data = array();
foreach ($iterator as $leafValue) {
if ( !$iterator -> hasChildren() ) {
if ($iterator->key() == 'id') {
$data[$leafValue]['id'] = $leafValue;
$id = $leafValue;
} else{
$data[$id][$iterator->key()] = $leafValue;
}
}
}
// output json
header('Content-Type: application/json');
echo json_encode($data, JSON_PRETTY_PRINT);
Output
{
"3": {
"id": 3,
"parent": 2,
"name": "Mike Jones"
},
"4": {
"id": 4,
"parent": 3,
"name": "Jason Williams"
},
"5": {
"id": 5,
"parent": 4,
"name": "Sara Johnson"
},
"7": {
"id": 7,
"parent": 2,
"name": "Amy Martin"
}
}

Categories