Create tree array

Hi,

This my first post in php section. i’m bit stucked with creating tree array.
I have to generate an array tree where each node have only one child and it ends for the node with “leaf” as true;

My input is an array of objects as mentioned below.


$first=new stdClass();
$first->id=1;
$first->leaf="false";
$fetype->text="Test1";

$sec=new stdClass();
$sec->id=2;
$sec->leaf="false";
$sec->text="Test2";

$third=new stdClass();
$third->id=3;
$third->leaf="false";
$third->text="Test3";

$four=new stdClass();
$four->id=4;
$four->leaf="true";
$four->text="Test4";

$newarr=array($first,$sec,$third,$four);

My out pattern have to be like this


$arr = array(array("id"=>1,"text"=>"Test1","leaf"=>false,"children"=>array(
                    array("id"=>2,"text"=>"Test2","leaf"=>false,"children"=>array(
                            array("id"=>3,"text"=>"Test3","leaf"=>false,"children"=>array(
                                    array("id"=>4,"text"=>"Test4","leaf"=>true)
                                )
                            )
                        )
                    )
                )
            )
        );

Hope someone will help me with this,

Thanks in advance

HI,

I was trying to generate a tree which shows parent node relation .
I have tried something like this and got desired result.


$i=0;
foreach($newarr as $key=>$value){
            $i++;
            if($i==1){
                $Noderoot = new Node($value->id,$value->text);
                $previousNode = $Noderoot;
            } else {
                $Nodechild = new Node($value->id,$value->text,$previousNode);
                $previousNode = $Nodechild;
            }
           
        }

Now i want generate a breadcrumb Using Node Class.
How could i generate that structure dynamically.

Hi,

Thanks, that generated what i needed :).

In which case, add the following function to the class I wrote above:

function asArray(){
    $output = array();
    $output['id'] = $this->ID;
    $output['text'] = $this->Name;
    $output['leaf'] = $this->isLeaf();
    if(!$output['leaf']){
        $output['children'] = array();
        foreach($this->Children as $Child){
            $output['children'][] = $Child->asArray();
        }
    }
    return $output;
}

Then to use it:

$Array = $Node1->asArray();

Hi,

I should have mentioned it before, i was trying to create a tree structure for EXTJS , for that the keys mentioned in Output array is needed. So that extjs will build a tree based on my response.

Thanks for your quick response.

Whilst objects are simply language constructs, I have to insist that, by using them, you adhere to object-oriented practices. Otherwise you may as well be using an array.

You wouldn’t necessarily need to specify if a node is a leaf by a property. Rather, simply allocate children to a node object - if that node has no children, it is a leaf.

For example:

class Node{
    protected $Children = array();
    protected $Parent = null;
    protected $Name, $ID;
    public function __Construct($ID, $Name, Node $Parent = null){
        $this->ID = $ID;
        $this->Name = $Name;
        if(!is_null($Parent)){
            $this->setParent($Parent);
        }
    }
    public function setParent(Node $Parent){
        $Parent->addChild($this);
        $this->Parent = $Parent;
    }
    public function getName(){
        return $this->Name;
    }
    public function getID(){
        return $this->ID;
    }
    public function addChild(Node $Child){
        $this->Children[] = $Child;
    }
    public function removeChild(Node $Child){
        $Item = array_search($Child, $this->Children);
        if($Item !== false){
            unset($this->Children[$Item]);
            $Child->setParent(null);
        }
    }
    public function isLeaf(){
        return (count($this->Children) == 0);
    }
    public function isRoot(){
        return is_null($this->Parent);
    }
    public function render(){
        if($this->isRoot()) echo '<ul>';
        echo '<li>' . $this->Name;
        if(!$this->isLeaf()){
            echo '<ul>';
                foreach($this->Children as $Child) $Child->render();
            echo '</ul>';
        }
        echo '</li>';
        if($this->isRoot()) echo '</ul>';
    }
}

And then your input becomes:

$Node1 = new Node(1, 'Test1');
$Node2 = new Node(2, 'Test2', $Node1);
$Node2_1 = new Node(5, 'Test2.1', $Node2);
$Node3 = new Node(3, 'Test3', $Node2);
$Node4 = new Node(4, 'Test4', $Node3);
$Node1->render();