I have a table in the database with the following structure/data:
n_id n_parent_id ... some other fields ...
==== =========== =========================
1 null ...
2 null ...
...
11 1 ...
12 1 ...
...
25 2 ...
...
65 11 ...
66 11 ...
...
This table stores hierarchical data, as can be seen from the sample above. I need to load this into a PHP array in a tree-like fasion, so that the array would contain something like this:
Array
(
[1] => Array
(
[n_id] => 1
[n_parent_id] =>
[other_data] => ...
[children] => Array
(
[11] => Array
(
[n_id] => 11
[n_parent_id] => 1
[other_data] => ...
[children] => Array
(
[65] => Array
(
[n_id] => 65
[n_parent_id] => 11
[other_data] => ...
)
)
... and so on ...
)
I can easily deal with one level:
//ordering will ensure that parent row is always read before children rows
//my data is set up in this way.
$query = "select n_id, n_parent_id, other_data from hierarchy_table order by n_parent_id, n_id";
if(($dbs = $dbh->query($query)) === FALSE) {
$e = $dbh->errorInfo();
// ... deal with error
}
$result = array();
while($row = $dbs->fetch(PDO::FETCH_ASSOC)) {
if(is_null($row['n_parent_id'])) {
$result[$row['n_id']] = array(
'n_id' => $row['n_id'],
'n_parent_id' => null,
'other_data' => ...,
'children' => array()
);
}
elseif(isset($result[$row['n_parent_id']])) {
$result[$row['n_parent_id']]['children'][$row['n_id']] = array(
'n_id' => $row['n_id'],
'n_parent_id' => $row['n_parent_id'],
'other_data' => ...
children => array()
);
}
}
However I can't seem to get my head around extending this to multiple levels without really having to loop recursively over the whole array every time I need to add a row. Naturally, had it been Java or C, I would just store pointers to data structures and that would solve the issue, but in PHP this isn't really that easy. At the end of this all, I will need to send the json_encode
of this to the client.
This question covers a similar issue, but I don't have the actual hierarchical information in the database - only parent id's.
Any help on this is appreciated.
EDIT: my database table contains hundreds of thousands of rows, therefore performance is important.