3

Here's the dataset in the mysql table:

Using the MySQL Nested Set model, it's not obvious, because I have left out the lft and rgt columns.

+------+----------+--------------------------------+-------+
+ Id   | ParentId | Name                           | Level |
+------+----------+--------------------------------+-------+
| 1001 |     NULL | Computing                      |     0 |
| 1002 |     NULL | Cassettes & Vinyl              |     0 |
| 1003 |     1001 | CD Players                     |     1 |
| 1004 |     1002 | CD Writers                     |     1 |
| 1005 |     1003 | CD-ROM Drives                  |     2 |
| 1006 |     1004 | CDs                            |     2 |
+------+----------+--------------------------------+-------+

This is pulled into a 2 dimensional array:

<?php
$data = array(
          array('id' => 1001, 'ParentId' => NULL, 'Name' => 'Computing', 'Level' => 0),
          array('id' => 1002, 'ParentId' => NULL, 'Name' => 'Cassettes & Vinyl', 'Level' => 0),
          array('id' => 1003, 'ParentId' => 1001, 'Name' => 'CD Players', 'Level' => 1),
          array('id' => 1004, 'ParentId' => 1002, 'Name' => 'CD Writers', 'Level' => 1),
          array('id' => 1005, 'ParentId' => 1003, 'Name' => 'CD-ROM Drives', 'Level' => 2),
          array('id' => 1006, 'ParentId' => 1004, 'Name' => 'Computing', 'Level' => 3)
        );
?>

I am trying to achieve the following multi-dimensional object:

stdClass Object {
    [0] => stdClass Object {
        [id] => 1001
        [name] => Computing
        [parentId] => NULL
        [level] => 0
        [children] => stdClass Object {
            [0] => stdClass Object {
                [id] => 1003
                [name] => CD Players
                [parentId] => 1001
                [level] => 1
                [children] => stdClass Object {
                    [0] => stdClass Object {
                        [id] => 1005
                        [name] => CD Rom Drives
                        [parentId] => 1003
                        [level] => 2
                    }
                }
            }
        }
    }
    [1] => stdClass Object {
        [id] => 1002
        [name] => Cassettes & Vinyl
        [parentId] => NULL
        [level] => 0
        [children] => stdClass Object {
            [0] => stdClass Object {
                [id] => 1004
                [name] => CD Writers
                [parentId] => 1002
                [level] => 1
                [children] => stdClass Object {
                    [0] => stdClass Object {
                        [id] => 1006
                        [name] => CDs
                        [parentId] => 1004
                        [level] => 2
                    }
                }
            }
        }
    }
}

I have been playing with a recursive function with little luck.

Why? - This object will be used to create for Zend_Navigation. I do not want to use an XML file at this stage, I prefer the taxonomy management to be done in the database.

Any ideas?

1 Answer 1

4

This is not necessarily a job for recursion, this can be done easily by iteration.

<?php

$data = array(
  array('id' => 1001, 'ParentId' => NULL, 'Name' => 'Computing', 'Level' => 0),
  array('id' => 1002, 'ParentId' => NULL, 'Name' => 'Cassettes & Vinyl', 'Level' => 0),
  array('id' => 1003, 'ParentId' => 1001, 'Name' => 'CD Players', 'Level' => 1),
  array('id' => 1004, 'ParentId' => 1002, 'Name' => 'CD Writers', 'Level' => 1),
  array('id' => 1005, 'ParentId' => 1003, 'Name' => 'CD-ROM Drives', 'Level' => 2),
  array('id' => 1006, 'ParentId' => 1004, 'Name' => 'Computing', 'Level' => 3)
);

$index = array();
$tree  = array();

// step 1: build index (note that I use &$row references!) 
foreach ($data as &$row) {
  $index[$row['id']] = &$row;
  $row['children'] = array();
  if ($row['ParentId'] == NULL) {
    $tree[] = &$row;
  }
}

// step 2: link tree (references here as well!)
foreach ($data as &$row) {
  $index[$row['ParentId']]['children'][] = &$row;
}

print_r($tree);

?>

result:

Array
(
  [0] => Array
  (
    [id] => 1001
    [ParentId] => 
    [Name] => Computing
    [Level] => 0
    [children] => Array
    (
      [0] => Array
      (
        [id] => 1003
        [ParentId] => 1001
        [Name] => CD Players
        [Level] => 1
        [children] => Array
        (
          [0] => Array
          (
            [id] => 1005
            [ParentId] => 1003
            [Name] => CD-ROM Drives
            [Level] => 2
            [children] => Array
            (
            )
          )
        )
      )
    )
  )
  [1] => Array
  (
    [id] => 1002
    [ParentId] => 
    [Name] => Cassettes & Vinyl
    [Level] => 0
    [children] => Array
    (
      [0] => Array
      (
        [id] => 1004
        [ParentId] => 1002
        [Name] => CD Writers
        [Level] => 1
        [children] => Array
        (
          [0] => Array
          (
            [id] => 1006
            [ParentId] => 1004
            [Name] => Computing
            [Level] => 3
            [children] => Array
            (
            )
          )
        )
      )
    )
  )
)
Sign up to request clarification or add additional context in comments.

2 Comments

Id the data was pulled from the database as an object with mysql_fetch_object, what would the code become?
What about using mysql_fetch_assoc()? That would be less hassle. Other than that, the code above is trivial enough. It should not be hard for you to make the necessary changes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.