Created
June 25, 2013 09:34
-
-
Save vv3d0x/5857216 to your computer and use it in GitHub Desktop.
PHP Tree builder used parent_id + level
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| //Input data | |
| $data = array( | |
| 0 => array( | |
| 'id' => 0, | |
| 'parent_id' => NULL, | |
| 'level' => 1, | |
| ), | |
| 1 => array( | |
| 'id' => 1, | |
| 'parent_id' => NULL, | |
| 'level' => 2, | |
| ), | |
| 2 => array( | |
| 'id' => 2, | |
| 'parent_id' => 1, | |
| 'level' => 3, | |
| ), | |
| 3 => array( | |
| 'id' => 3, | |
| 'parent_id' => 1, | |
| 'level' => 2, | |
| ), | |
| 4 => array( | |
| 'id' => 4, | |
| 'parent_id' => 3, | |
| 'level' => 3, | |
| ), | |
| 5 => array( | |
| 'id' => 5, | |
| 'parent_id' => 1, | |
| 'level' => 2, | |
| ), | |
| 6 => array( | |
| 'id' => 6, | |
| 'parent_id' => NULL, | |
| 'level' => 1, | |
| ), | |
| ); | |
| //Using | |
| $builder = new TreeBuilder($data); | |
| $tree = $builder->build(); | |
| //TreeBuilder | |
| class TreeBuilder { | |
| /*** | |
| * Base in data | |
| * @var array | |
| */ | |
| protected $data = array(); | |
| protected $relations = array(); | |
| /*** | |
| * Tree data | |
| * @var array | |
| */ | |
| protected $tree = array(); | |
| /*** | |
| * Array of items for tree building | |
| * @param array $data | |
| */ | |
| public function __construct($data = array()) { | |
| $this->data = $data; | |
| } | |
| public function build() { | |
| $items = &$this->getData(); | |
| $this->buildDescendantsRelations(); | |
| foreach ($items as $k => $v) { | |
| if ($v['parent_id'] === NULL) { | |
| array_push($this->tree, $this->buildNodeTree($k, $this->relations)); | |
| } | |
| } | |
| return $this->tree; | |
| } | |
| public function buildNodeTree($root_id = 0, &$descendants = array()) { | |
| $tree = array( | |
| 'id' => $root_id, | |
| ); | |
| if(isset($descendants[$root_id])) { | |
| foreach ($descendants[$root_id] as &$item) { | |
| $tree['descendants'][] = $this->buildNodeTree($item, $descendants); | |
| } | |
| unset($item); | |
| } | |
| return $tree; | |
| } | |
| /* | |
| * Build descendants relations | |
| * Array root_id => array children_id | |
| * */ | |
| public function buildDescendantsRelations() { | |
| $items = &$this->getData(); | |
| foreach ($items as $k => $v) { | |
| $id = ($v['parent_id'] === NULL) ? NULL : (int)$v['parent_id']; | |
| if ($id !== NULL) { | |
| if(!isset($this->relations[$id])) { | |
| $this->relations[$id] = array(); | |
| } | |
| array_push($this->relations[$id], $k); | |
| } | |
| } | |
| } | |
| public function getTree() { | |
| return $this->tree; | |
| } | |
| public function &getRelations() { | |
| return $this->relations; | |
| } | |
| protected function &getData() { | |
| return $this->data; | |
| } | |
| } | |
| //All code for level control is removed |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
hi,
i think the "closure table" pattern is better. Look at this :
http://karwin.blogspot.de/2010/03/rendering-trees-with-closure-tables.html
http://fr.slideshare.net/billkarwin/models-for-hierarchical-data