Creating a PHP/MySQL Tree
- xclanet
- Born


- Joined: Mar 02, 2011
- Posts: 3
- Status: Offline
I was messing arround with code and i can't figure out to do this:
See attached image.
I have a Table in the database like this:
CREATE TABLE IF NOT EXISTS `nodetree` (
`node` int(11) NOT NULL,
`prevnode` int(11) NOT NULL,
`nextnode` int(11) NOT NULL,
`nodename` varchar(30) NOT NULL,
`nodelink` varchar(255) NOT NULL,
PRIMARY KEY (`node`,`prevnode`, `nextnode`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
What i want to do is to get php build that graph automatically with tables. Each node is a clickable link to node description.
Thanks in advance.
See attached image.
I have a Table in the database like this:
CREATE TABLE IF NOT EXISTS `nodetree` (
`node` int(11) NOT NULL,
`prevnode` int(11) NOT NULL,
`nextnode` int(11) NOT NULL,
`nodename` varchar(30) NOT NULL,
`nodelink` varchar(255) NOT NULL,
PRIMARY KEY (`node`,`prevnode`, `nextnode`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
What i want to do is to get php build that graph automatically with tables. Each node is a clickable link to node description.
Thanks in advance.
Attachments:
- Anonymous
- Bot


- Joined: 25 Feb 2008
- Posts: ?
- Loc: Ozzuland
- Status: Online
March 2nd, 2011, 9:19 am
- gisele
- Expert


- Joined: Nov 11, 2004
- Posts: 583
- Loc: Nimes (France)
- Status: Offline
Hi,
the really indicated approach in that case is the use of a recursive function.
I see 3 little classes.
I see a class "node" witch would be a kind of POPO (Plain-Old PHP Object), simple value object containing only accessors (getPrev(), getName() ...)and mutators (setPrev(), setName()) just like beans / POJO java objects.
I see a NodeDao that maps the node object attributes with table fields name and do Read/write operation in db.
the methods are like that :
Node NodeDao::find(Node $node) => you just set the ID to the Node object and ask DAO to find and fullfill it.
array NodeDao::getChild(Node $node) => this method list children and return a collection of Node objects
Node NodeDao::Create(Node $createMe)
SQL statments are only in the DAO of course.
etc.
Then you can make a function or a method that can be called recursivly :
Il you want more details on how to implement a DAO (Data access object ) feel free to ask.
If you are < PHP5 change the methods signature (remove the type hiting).
be careful to not repeat twice the same node id as a child in your table unless you fall into an aternel loop
the really indicated approach in that case is the use of a recursive function.
I see 3 little classes.
I see a class "node" witch would be a kind of POPO (Plain-Old PHP Object), simple value object containing only accessors (getPrev(), getName() ...)and mutators (setPrev(), setName()) just like beans / POJO java objects.
I see a NodeDao that maps the node object attributes with table fields name and do Read/write operation in db.
the methods are like that :
Node NodeDao::find(Node $node) => you just set the ID to the Node object and ask DAO to find and fullfill it.
array NodeDao::getChild(Node $node) => this method list children and return a collection of Node objects
Node NodeDao::Create(Node $createMe)
SQL statments are only in the DAO of course.
etc.
Then you can make a function or a method that can be called recursivly :
Code: [ Select ]
buildNode (NodeDao $dao, Node $node)
{
[... here the code to build current cliquable node ...]
//are there children?
$nodeList = $dao->getChildren($node);
foreach ($nodeList as $childNode){
buildNode($dao, $childNode);// this the recursive call to the same build method foreach child found
}
}
{
[... here the code to build current cliquable node ...]
//are there children?
$nodeList = $dao->getChildren($node);
foreach ($nodeList as $childNode){
buildNode($dao, $childNode);// this the recursive call to the same build method foreach child found
}
}
- buildNode (NodeDao $dao, Node $node)
- {
- [... here the code to build current cliquable node ...]
- //are there children?
- $nodeList = $dao->getChildren($node);
- foreach ($nodeList as $childNode){
- buildNode($dao, $childNode);// this the recursive call to the same build method foreach child found
- }
- }
Il you want more details on how to implement a DAO (Data access object ) feel free to ask.
If you are < PHP5 change the methods signature (remove the type hiting).
be careful to not repeat twice the same node id as a child in your table unless you fall into an aternel loop
____________________
My web site[/url] oh sh..!
My web site[/url] oh sh..!
- gisele
- Expert


- Joined: Nov 11, 2004
- Posts: 583
- Loc: Nimes (France)
- Status: Offline
Well, I feel like I should just add a couple of key informations.
1/ How should your process begin?
something like that
That's it, we launched the whole treeView building since treeViewBuilder::build() we automatically go on recursivly while it will find children.
2. what does treevView builder class look like?
class TreeViewBuilder
/**
* build the current node
* @param NodeDao
* @param Node
* @return string html string
*/
public method buildNode (NodeDao $O_dao, Node $O_node)
{
$S_html = '';
/** [... here the code to build current cliquable node ($S_html), using info returned by Node object accessors...] */
//are there children?
$A_nodeList = $o_dao->getChildren($O_node);
foreach ($A_nodeList as $O_childNode){
$S_html .= $this->buildNode($O_dao, $O_childNode);// this the recursive call to the same build method foreach child found
}
return $S_html;
}
}
3/ What does a DAO look like?
let's show examples of DAO methods
4/ what does a POPO like?
Node class is much more simple since it just has node encapsulated attributes, accessors and mutator.
It is manipulated by the Dao pour DB operations and the treev viewBuilder to retrieve node information on current node to build.
1/ How should your process begin?
something like that
Code: [ Select ]
//assuming we have the root node id whatever the one it is in db
//you need a Dao instance
$O_dao = new NodeDao()
//build the root node and set its known id and ask DAO to fill it
$O_rootNode = new Node();
$O_rootNode->setId($S_rootId);//
$O_rootNode = $dao->find($rootNode);
//we have the root POPO node filled so let's build the treeview
$O_treeViewBuilder = new TreeViewBuilder();
//the method we call is the same that "buildTreview()" above but let's put the method in a class
$O_treeViewBuilder->build($O_dao, $O_rootNode);
//you need a Dao instance
$O_dao = new NodeDao()
//build the root node and set its known id and ask DAO to fill it
$O_rootNode = new Node();
$O_rootNode->setId($S_rootId);//
$O_rootNode = $dao->find($rootNode);
//we have the root POPO node filled so let's build the treeview
$O_treeViewBuilder = new TreeViewBuilder();
//the method we call is the same that "buildTreview()" above but let's put the method in a class
$O_treeViewBuilder->build($O_dao, $O_rootNode);
- //assuming we have the root node id whatever the one it is in db
- //you need a Dao instance
- $O_dao = new NodeDao()
- //build the root node and set its known id and ask DAO to fill it
- $O_rootNode = new Node();
- $O_rootNode->setId($S_rootId);//
- $O_rootNode = $dao->find($rootNode);
- //we have the root POPO node filled so let's build the treeview
- $O_treeViewBuilder = new TreeViewBuilder();
- //the method we call is the same that "buildTreview()" above but let's put the method in a class
- $O_treeViewBuilder->build($O_dao, $O_rootNode);
That's it, we launched the whole treeView building since treeViewBuilder::build() we automatically go on recursivly while it will find children.
2. what does treevView builder class look like?
Code: [ Select ]
class TreeViewBuilder
/**
* build the current node
* @param NodeDao
* @param Node
* @return string html string
*/
public method buildNode (NodeDao $O_dao, Node $O_node)
{
$S_html = '';
/** [... here the code to build current cliquable node ($S_html), using info returned by Node object accessors...] */
//are there children?
$A_nodeList = $o_dao->getChildren($O_node);
foreach ($A_nodeList as $O_childNode){
$S_html .= $this->buildNode($O_dao, $O_childNode);// this the recursive call to the same build method foreach child found
}
return $S_html;
}
}
- class TreeViewBuilder
- /**
- * build the current node
- * @param NodeDao
- * @param Node
- * @return string html string
- */
- public method buildNode (NodeDao $O_dao, Node $O_node)
- {
- $S_html = '';
- /** [... here the code to build current cliquable node ($S_html), using info returned by Node object accessors...] */
- //are there children?
- $A_nodeList = $o_dao->getChildren($O_node);
- foreach ($A_nodeList as $O_childNode){
- $S_html .= $this->buildNode($O_dao, $O_childNode);// this the recursive call to the same build method foreach child found
- }
- return $S_html;
- }
- }
3/ What does a DAO look like?
let's show examples of DAO methods
Code: [ Select ]
class NodeDao
{
/**
* find a Node in DB
* @param Node
* @return Node
*/
public function find(Node $O_node)
{
if(!$O_node->getId()) {
throw new Exception ('Node object should have an Id');
}
$S_sql = 'select ..... where node = \'' . mysql_real_escape_string($O_node->getId()) . '\'';
$recordset = mysql_query($S_sql);
if($A_row = mysql_fetch_assoc($R_recordset))
{
$O_nodeFind = clone $O_node;
$O_nodeFind->setName($A_row['nodename']);
$O_nodeFind->setLink($A_row['nodelink']);
//etc.
return $O_nodeFind;
}
else {
throw new Exception ('Node "' .$node->getId(). '" not Find');
}
return $nodeFind;
}
/**
* Find the children of a given node
* @param Node
* @return Node
*/
public function getChildren(Node $O_parent)
{
if(!$O_parent->getId()) {
throw new Exception ('Parent Node object should have an Id');
}
$A_found = array();
$S_sql = 'select ..... where prevnode = \'' . mysql_real_escape_string($O_parent->getId()) . '\'';
$R_recordset = mysql_query($S_sql);
while($A_row = mysql_fetch_assoc($R_recordset))
{
$O_nodeFind = clone $node;
$O_nodeFind->setId($A_row['node']);
$O_nodeFind->setName($A_row['nodename']);
$O_nodeFind->setLink($A_row['nodelink']);
//etc.
$A_found[$O_nodeFind->getId()] = $O_nodeFind;
}
return $A_found;
}
//etc. use Node accessor for whrite methods like create (for insertion), delete, update
{
/**
* find a Node in DB
* @param Node
* @return Node
*/
public function find(Node $O_node)
{
if(!$O_node->getId()) {
throw new Exception ('Node object should have an Id');
}
$S_sql = 'select ..... where node = \'' . mysql_real_escape_string($O_node->getId()) . '\'';
$recordset = mysql_query($S_sql);
if($A_row = mysql_fetch_assoc($R_recordset))
{
$O_nodeFind = clone $O_node;
$O_nodeFind->setName($A_row['nodename']);
$O_nodeFind->setLink($A_row['nodelink']);
//etc.
return $O_nodeFind;
}
else {
throw new Exception ('Node "' .$node->getId(). '" not Find');
}
return $nodeFind;
}
/**
* Find the children of a given node
* @param Node
* @return Node
*/
public function getChildren(Node $O_parent)
{
if(!$O_parent->getId()) {
throw new Exception ('Parent Node object should have an Id');
}
$A_found = array();
$S_sql = 'select ..... where prevnode = \'' . mysql_real_escape_string($O_parent->getId()) . '\'';
$R_recordset = mysql_query($S_sql);
while($A_row = mysql_fetch_assoc($R_recordset))
{
$O_nodeFind = clone $node;
$O_nodeFind->setId($A_row['node']);
$O_nodeFind->setName($A_row['nodename']);
$O_nodeFind->setLink($A_row['nodelink']);
//etc.
$A_found[$O_nodeFind->getId()] = $O_nodeFind;
}
return $A_found;
}
//etc. use Node accessor for whrite methods like create (for insertion), delete, update
- class NodeDao
- {
- /**
- * find a Node in DB
- * @param Node
- * @return Node
- */
- public function find(Node $O_node)
- {
- if(!$O_node->getId()) {
- throw new Exception ('Node object should have an Id');
- }
- $S_sql = 'select ..... where node = \'' . mysql_real_escape_string($O_node->getId()) . '\'';
- $recordset = mysql_query($S_sql);
- if($A_row = mysql_fetch_assoc($R_recordset))
- {
- $O_nodeFind = clone $O_node;
- $O_nodeFind->setName($A_row['nodename']);
- $O_nodeFind->setLink($A_row['nodelink']);
- //etc.
- return $O_nodeFind;
- }
- else {
- throw new Exception ('Node "' .$node->getId(). '" not Find');
- }
- return $nodeFind;
- }
- /**
- * Find the children of a given node
- * @param Node
- * @return Node
- */
- public function getChildren(Node $O_parent)
- {
- if(!$O_parent->getId()) {
- throw new Exception ('Parent Node object should have an Id');
- }
- $A_found = array();
- $S_sql = 'select ..... where prevnode = \'' . mysql_real_escape_string($O_parent->getId()) . '\'';
- $R_recordset = mysql_query($S_sql);
- while($A_row = mysql_fetch_assoc($R_recordset))
- {
- $O_nodeFind = clone $node;
- $O_nodeFind->setId($A_row['node']);
- $O_nodeFind->setName($A_row['nodename']);
- $O_nodeFind->setLink($A_row['nodelink']);
- //etc.
- $A_found[$O_nodeFind->getId()] = $O_nodeFind;
- }
- return $A_found;
- }
- //etc. use Node accessor for whrite methods like create (for insertion), delete, update
4/ what does a POPO like?
Node class is much more simple since it just has node encapsulated attributes, accessors and mutator.
It is manipulated by the Dao pour DB operations and the treev viewBuilder to retrieve node information on current node to build.
Code: [ Select ]
class Node
{
protected $_S_id://node ID
protected $_S_name;
protected $_S_prev;
//etc.
/**
* allows to get node Id
* @return string
*/
public function getId()
{
return $this->_S_id;
}
/**
* allows to set node Id
* @param string
*/
public function setId($S_id)
{
$this->_S_id = (string) $S_id;
}
//etc.
}
{
protected $_S_id://node ID
protected $_S_name;
protected $_S_prev;
//etc.
/**
* allows to get node Id
* @return string
*/
public function getId()
{
return $this->_S_id;
}
/**
* allows to set node Id
* @param string
*/
public function setId($S_id)
{
$this->_S_id = (string) $S_id;
}
//etc.
}
- class Node
- {
- protected $_S_id://node ID
- protected $_S_name;
- protected $_S_prev;
- //etc.
- /**
- * allows to get node Id
- * @return string
- */
- public function getId()
- {
- return $this->_S_id;
- }
- /**
- * allows to set node Id
- * @param string
- */
- public function setId($S_id)
- {
- $this->_S_id = (string) $S_id;
- }
- //etc.
- }
____________________
My web site[/url] oh sh..!
My web site[/url] oh sh..!
- xclanet
- Born


- Joined: Mar 02, 2011
- Posts: 3
- Status: Offline
- SpooF
- ٩๏̯͡๏۶


- Joined: May 22, 2004
- Posts: 3415
- Loc: Richland, WA
- Status: Offline
- gisele
- Expert


- Joined: Nov 11, 2004
- Posts: 583
- Loc: Nimes (France)
- Status: Offline
Sorry,
in that case you will have to separate node notion and relation notion.
Relation object would be associations between 2 nodes(a parent- a child)
One step would to list node objects and build a node grid depending on X-Y Positions.
the sd step would be to list and lie on the grid the relations depending on parentX parent Y - child X child Y.
Anyway I think it's important to separate the grid logic and the relation logic so that the latter uses the former for its own representation.
You could also search for site map algorithms since it looks like the same problem.
in that case you will have to separate node notion and relation notion.
Relation object would be associations between 2 nodes(a parent- a child)
One step would to list node objects and build a node grid depending on X-Y Positions.
the sd step would be to list and lie on the grid the relations depending on parentX parent Y - child X child Y.
Anyway I think it's important to separate the grid logic and the relation logic so that the latter uses the former for its own representation.
You could also search for site map algorithms since it looks like the same problem.
____________________
My web site[/url] oh sh..!
My web site[/url] oh sh..!
- xclanet
- Born


- Joined: Mar 02, 2011
- Posts: 3
- Status: Offline
SpooF wrote:
Are you looking for a way to show the tree graphically or just represent it in code?
both.
gisele wrote:
Sorry,
in that case you will have to separate node notion and relation notion.
Relation object would be associations between 2 nodes(a parent- a child)
One step would to list node objects and build a node grid depending on X-Y Positions.
the sd step would be to list and lie on the grid the relations depending on parentX parent Y - child X child Y.
Anyway I think it's important to separate the grid logic and the relation logic so that the latter uses the former for its own representation.
You could also search for site map algorithms since it looks like the same problem.
in that case you will have to separate node notion and relation notion.
Relation object would be associations between 2 nodes(a parent- a child)
One step would to list node objects and build a node grid depending on X-Y Positions.
the sd step would be to list and lie on the grid the relations depending on parentX parent Y - child X child Y.
Anyway I think it's important to separate the grid logic and the relation logic so that the latter uses the former for its own representation.
You could also search for site map algorithms since it looks like the same problem.
I am searching it's been now 1 week... and i don't find anything that can leads me to something near.
Page 1 of 1
To Reply to this topic you need to LOGIN or REGISTER. It is free.
Post Information
- Total Posts in this topic: 7 posts
- Users browsing this forum: No registered users and 122 guests
- You cannot post new topics in this forum
- You cannot reply to topics in this forum
- You cannot edit your posts in this forum
- You cannot delete your posts in this forum
- You cannot post attachments in this forum
