Entrei rapidinho pra postar um bebê meu, que foi criado para ser extendido em inúmeros outros módulos.
Trata-se de uma estrutura de árvore genérica, com suporte a comentários e talz.
A intenção é extender a classe, e não utilizá-la de qualquer lado.
Finalizei uma extensão dela também, mas não vou publicá-la ainda... não foi registrada ainda!

Trata-se de uma TAD (Tipo Abstrato de Dados) Árvore, genérico, com suporte a qualquer quantidade de nós filhos, e folhas...
Criei uma rápida documentação sobre ela usando o PHP Documentor 1.3 RC 3... que eu tenho instalado em casa.
AHHHHHH.... esqueci de comentar que ela só suporta PHP5+
A um certo tempo só tenho trabalho com a versão 5... MUITO MAIS ESTÁVEL que a 4... não tem nem comparação!!!!
Os sources vou colocar aqui... mas são BEM extensos!!! Sugiro que peguem o ZIP no final do post.
Grato,
Arquivo: class.pTree.php
<?php
/**
 * pTree - Generic Tree Implementation
 *
 * This class provides a Tree Data Structure implementation
 *
 * @package pTree
 * @created 2005-02-20 01:04 GMT - 3:00hs
 * @updated 2005-02-20 20:28 GMT - 3:00hs
 *
 * @author Guilherme Blanco <guilhermeblanco@gmail.com>
 * @copyright Copyright® 2005, PontUKom Corp
 *
 * @version 1.0 Corrected isRoot, hasChilds, hasValue 
 *              Avoid removed nodes wrong parsing
 * @version 0.9 First public release
 *
 * @access protected
 */
/**
 * @global boolean Tree Data Structure Loaded
 */
if (!defined("ADT_TREE"))
    define("ADT_TREE", 1);
class pTree extends pTreeNode
{
    /**
     * @var string $separator Tree Path Separator
     * @access protected
     */
    protected $separator = "/";
    /**
     * Constructor - Generates a Tree Data Structure
     *
     * @access public
     * @param string $treeSeparator Path Char Separator
     * @param string $rootName Name of Root
     * @return object $this Tree
     */
    public function __construct($treeSeparator = "/", $rootName = "root")
    {
        parent::__construct($rootName);
        $this->separator = $treeSeparator;
    }
    /**
     * Add - Insert OR Update Tree Node with Value
     *
     * @access public
     * @param mixed $node Node Path or Object
     * @param mixed $value Node Value
     * @return object $treeNode Tree Node Created OR Updated
     */
    public function add($node, $value = null)
    {
        // Grabbing Node
        $treeNode = $this->getChild($node);
        
        // Retrieving basename
        $nodeName = $this->getLastName($node);
        // Checking possible node update
        if ($treeNode->getName() == $nodeName)
            // Node update
            $treeNode->setValue($value);
        else
            // Creating and returning Node
            $treeNode = $treeNode->addChild($nodeName, $value);
        // Returning Node
        return $treeNode;
    }
    /**
     * Remove - Remove Tree Node and All Sub-Childs
     *
     * @access public
     * @param mixed $node Node Name or Object
     */
    public function remove($node)
    {
        // Grabbing Node
        $treeNode = $this->getChild($node);
        // Retrieving Parent Node
        $parentNode = $treeNode->getParent();
        // Removing Node
        $parentNode->removeChild($treeNode);
    }
    /**
     * Get - Retrieves Node Value
     *
     * @access public
     * @param mixed $node Node Path or Object
     * @return mixed $nodeValue Tree Node Value
     */
    public function get($node)
    {
        // Grabbing Node
        $treeNode = $this->getChild($node);
        // Retrieving Node Value
        return $treeNode->getValue();
    }
    /**
     * Comment - Insert a Tree Node Comment
     *
     * @access public
     * @param mixed $node Node Name or Object
     * @param string $comment Node Comment
     */
    public function comment($node, $comment)
    {
        // Grabbing Node
        $treeNode = $this->getChild($node);
        // Inserting Node Comment
        $treeNode->addComment($comment);
    }
    /**
     * Get Child - Retrieve a Child Node of Tree
     *
     * @access protected
     * @param string $nodeName Name of Child Node
     * @return mixed $treeNode Tree Node
     */
    protected function getChild($nodeName)
    {
        // Splitting Path in an array
        $arr = explode($this->separator, trim(str_replace(" ", "_", $nodeName)));
        $child_block = $this;
        // Retrieving Node Inheritance
        for ($i = 0; $i < count($arr); $i++)
        {
            if (array_key_exists($arr[$i], $child_block->getAllChilds()))
                $child_block = $child_block->getChildNode($arr[$i]);
        }
        // Returning Node
        return $child_block;
    }
    /**
     * Get Root - Retrieve Root Node
     *
     * @access public
     * @return object $this Root Node of Tree
     */
    public function getRoot()
    {
        return $this;
    }
    /**
     * Is Root - Checks if a given Tree Node is the Root of Tree
     *
     * @access public
     * @param string $node Node Name
     * @return boolean $boolReturn Returns TRUE is Tree Node is the Root of the Tree; FALSE instead
     */
    public function isRoot($node)
    {
        // Grabbing Node
        $possRoot = $this->getChild($node);
        // Retrieving basename
        $nodeName = $this->getLastName($node);
        if ($possRoot->getName() === $nodeName && $possRoot->getParent() === $this)
            return true;
        else
            return false;
    }
    /**
     * Has Childs - Checks if a Tree Node has Childs or not
     *
     * @access public
     * @param string $node Node Name
     * @return boolean $boolReturn Returns TRUE is Tree Node has Childs and FALSE if not
     */
    public function hasChilds($node)
    {
        // Getting Node
        $treeNode = $this->getChild($node);
        // Retrieving basename
        $nodeName = $this->getLastName($node);
        if ($treeNode->getName() === $nodeName && count($treeNode->getAllChilds()) > 0)
            return true;
        return false;
    }
    /**
     * Has Value - Checks if a Tree Node has Value or not
     *
     * @access public
     * @param string $node Node Name
     * @return boolean $boolReturn Returns TRUE is Tree Node has Value; FALSE instead
     */
    public function hasValue($node)
    {
        // Getting Node
        $treeNode = $this->getChild($node);
        // Retrieving basename
        $nodeName = $this->getLastName($node);
        if ($treeNode->getName() === $nodeName && $treeNode->getValue() != null)
            return true;
        return false;
    }
    /**
     * To String - Creates a Human readable output of Tree Node
     *
     * @access public
     * @param integer $mode Output Mode
     * @return string $output Formatted readable output of Tree
     */
    public function toString($mode = 0)
    {
        $str = "";
        // Building formatted output of first level child Nodes
        foreach ($this->childNodes as $block_name => $block)
            $str .= $block->toString($mode);
        return $str;
    }
    /**
     * Get Last Name - Retrieves the basename of a given Node Path
     *
     * @access protected
     * @param string $nodePath Tree Node Path
     * @return string $nodeName Tree Node Basename (Node Name)
     */
    protected function getLastName($nodePath)
    {
        return substr(trim(str_replace(" ", "_", $nodePath)), ((strrpos($nodePath, $this->separator) == false) ? 0 : strrpos($nodePath, $this->separator) + 1), strlen($nodePath));
    }
};
/**
 * pTreeNode - Generic Node for Tree Implementation
 *
 * This class provides a Tree Node definition for generic tree data structure implementation
 *
 * @package pTreeNode
 * @created 2005-02-19 16:04 GMT - 3:00hs
 * @updated No updates yet
 *
 * @author Guilherme Blanco <guilhermeblanco@gmail.com>
 * @copyright Copyright® 2005, PontUKom Corp
 *
 * @version 1.0 First public release
 *
 * @access protected
 */
class pTreeNode
{
    /**
     * @var string $name Node Name
     * @access protected
     */
    protected $name = "";
    /**
     * @var string $value Node Value
     * @access protected
     */
    private $value = null;
    /**
     * @var object $parentNode Parent TreeNode Reference
     * @access protected
     */
    private $parentNode = null;
    /**
     * @var string $comment Node Comment
     * @access protected
     */
    private $comment = "";
    /**
     * @var array $childNodes Child Nodes
     * @access protected
     */
    protected $childNodes = array();
    /**
     * @var integer $depth Depth of Node
     * @access protected
     */
    private $depth = -1;
    /**
     * Constructor - Should not be called directly. Please use {@link addChild} instead.
     *
     * @access public
     * @param string $nodeName Name of Tree Node
     * @param object $parentNode Parent Tree Node reference, if any
     * @return object $this Tree Node
     * @see addChild
     */
    public function __construct($nodeName, $parentNode = null)
    {
        $this->name = trim(str_replace(" ", "_", $nodeName));
        // Checking level
        if ($parentNode != null)
        {
            $this->parentNode = $parentNode;
            $this->depth = $parentNode->depth + 1;
            $parentNode->childNodes[$this->name] = $this;
        }
    }
    /**
     * Destructor - Should not be called directly. This does the same as {@link removeAllChilds} method.
     *
     * @access private
     * @see removeAllChilds
     */
    public function __destruct()
    {
        $this->removeAllChilds();
    }
    /**
     * Get Child - Retrieve a Child Node of the given Tree Node
     *
     * @access protected
     * @param string $nodeName Name of Child Node
     * @return mixed $treeNode Tree Node
     */
    protected function getChildNode($nodeName)
    {
        return ((array_key_exists($nodeName, $this->childNodes)) ? $this->childNodes[$nodeName] : null);
    }
    /**
     * Get All Childs - Retrieve All Child Nodes of the given Tree Node
     *
     * @access protected
     * @return array $arrayTreeNodes Tree Nodes array
     */
    protected function getAllChilds()
    {
        return $this->childNodes;
    }
    /**
     * Remove Child - Remove Child Node
     *
     * @access protected
     * @param mixed $node Name of Child Node or Child Tree Node Object
     * @return boolean $boolRemoved TRUE
     * @see removeAllChilds
     */
    protected function removeChild($node)
    {
        // Retrieve Node, if node is a string
        $nodeItem = (!is_object($node)) ? $this->getChild($node) : $node;
        // Remove sub-Childs of Child
        $nodeItem->removeAllChilds();
        // Removing from Parent Tree Node
        $this->childNodes[$nodeItem->name] = null;
        unset($this->childNodes[$nodeItem->name]);
        unset($nodeItem);
        return true;
    }
    /**
     * Remove All Childs - Remove All Child Nodes
     *
     * @access protected
     * @return boolean $boolRemoved TRUE
     */
    protected function removeAllChilds()
    {
        // Removing childs
        foreach ($this->childNodes as $key => $value)
        {
            $this->childNodes[$key]->removeAllChilds();
            $this->childNodes[$key] = null;
            unset($this->childNodes[$key]);
        }
        $this->childNodes = array();
        $this->value = null;
    }
    /**
     * Add - Add a Tree Node with Value
     *
     * @access protected
     * @param string $node Node Name
     * @param mixed $value Value of new Node
     * @return object $generatedTreeNode Generated Tree Node
     */
    protected function addChild($node, $value = null)
    {
        // Tree Node doesn't exist; create one
        $nodeItem = new pTreeNode($node, $this);
        // Set up a Value
        $nodeItem->setValue($value);
        // Return new Tree Node
        return $nodeItem;
    }
    /**
     * Get Parent - Retrieve the parent Tree Node of item, or item if none
     *
     * @access public
     * @return object $treeNode Tree Node
     */
    public function getParent()
    {
        return (($this->parentNode != null) ? $this->parentNode : $this);
    }
    /**
     * Set Value - Set up a Value in Tree Node
     *
     * @access protected
     * @param mixed $nodeValue Value of a Tree Node
     */
    protected function setValue($nodeValue)
    {
        $this->value = $nodeValue;
    }
    /**
     * Get Value - Get the Value of given Tree Node
     *
     * @access public
     * @return mixed $nodeValue Value of Tree Node
     */
    public function getValue()
    {
        return $this->value;
    }
    /**
     * Get Depth - Grab Tree Node Depth
     *
     * @access public
     * @return integer $nodeDepth Depth of Tree Node
     */
    public function getDepth()
    {
        return $this->depth;
    }
    /**
     * Get Name - Retrieve Tree Node Name
     *
     * @access public
     * @return string $nodeName Name of Tree Node
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * Add Comment - Set up a Tree Node Comment
     *
     * @access protected
     * @param string $nodeComment Comment of Tree Node
     */
    protected function addComment($nodeComment = "")
    {
        $this->comment = $nodeComment;
    }
    /**
     * To String - Creates a Human readable output of Tree Node (reverse of {@link fromString} method)
     *
     * @access public
     * @param integer $mode Output Mode
     * @return string $output Formatted readable output of Tree
     * @see fromString
     */
    public function toString($mode = 0)
    {
        // Checking Mode Variables
        $creturn = (($mode === 0) ? "<br />" : "\r\n");
        $blank = (($mode === 0) ? " " : " ");
        $ident = str_repeat($blank, 4 * $this->depth);
        $str = "";
        // Building Node Comment
        if ($this->comment != "")
            $str .= $ident."#".$blank.str_replace(array("<br />", "<br>", "\r\n", "\n"), $creturn.$ident."#".$blank, $this->comment).$creturn;
        // Create Node
        $str .= $ident."[".$this->name." = ".$this->parseValue($this->value)."] {".((count($this->childNodes) > 0) ? $creturn : "");
        // Creating inner Nodes
        foreach ($this->childNodes as $block_name => $block)
            $str .= $block->toString($mode);
        // Finishing Node
        $str .= ((count($this->childNodes) > 0) ? $ident : "")."}".$creturn;
        // Returning...
        return $str;
    }
    /**
     * From String - Generates Tree Structure using Formatted String Entry (reverse of {@link toString} method)
     *
     * @access public
     * @param string $input Formatted input of Tree
     * @return object $this Tree
     * @see toString
     */
    public function fromString($input = "")
    {
        // No String, return
        if ($input == "") return;
        $curObj = $this;
        $curComment = "";
        // Wrap new lines
        $lines = explode("\n", $input);
        foreach ($lines as $line)
        {
            $line = trim(str_replace("\r", "", $line));
            // Comment line
            if (eregi('#(.*)', $line, $res))
                $curComment .= trim($res[1])."\n";
            // Node definition
            elseif (eregi('\[(.[^=]*)\s*=\s*(.*)\]\s*(.*)', $line, $res))
            {
                $value = $this->parseValue($res[2], 1);
                $curObj = $curObj->addChild(trim($res[1]), $value);
                $curObj->addComment(substr($curComment, 0, strlen($curComment) - 1));
                if (strstr($res[3], "}"))
                    $curObj = $curObj->getParent();
                $curComment = "";
            }
            // Bracket close
            elseif (substr($line, 0, 1) == "}")
                $curObj = $curObj->getParent();
            unset($res);
            unset($line);
        }
        // Checking error
        if ($curObj !== $this)
            trigger_error("<b>Tree:</b> Missing brackets in Node [".$curObj->getName()."]", E_USER_ERROR);
    }
    /**
     * Parse Value - Encode/Decode Value parameter
     *
     * @access private
     * @param mixed $nodeValue Value of Node (encoded or decoded)
     * @param integer $type Type of processment: [0] Encode / [1] Decode
     * @return mixed $nodeValue Value of Node
     */
    private function parseValue($nodeValue, $type = 0)
    {
        // Encode Type (Called with type argument set as 0 [default])
        if ($type == 0)
        {
            // Array
            if (is_array($nodeValue))
            {
                $newNodeValue = "(";
                foreach ($nodeValue as $key => $value)
                    $newNodeValue .= ((is_numeric($key)) ? $key : "\"".$key."\"")." => ".((is_numeric($value)) ? $value : "\"".$value."\"").", ";
                $newNodeValue = substr($newNodeValue, 0, strlen($newNodeValue) - 2).")";
            }
            // Object
            elseif (is_object($nodeValue))
                $newNodeValue = serialize($nodeValue);
            // String
            elseif (!is_numeric($nodeValue))
                $newNodeValue = "\"".$nodeValue."\"";
            // Number
            else
                $newNodeValue = $nodeValue;
        }
        // Decode Type (Called with type argument set and different of 0)
        else
        {
           $nodeValue = trim($nodeValue);
           // Array
           if (substr($nodeValue, 0, 1) == "(")
           {
               $newNodeValue = array();
               eregi('\((.[^\)]*)\)', $nodeValue, $nodeValue);
               $nodeValue= $nodeValue[1];
               $itens = explode(",", $nodeValue);
               for ($i = 0; $i < count($itens); $i++)
               {
                   eregi("[\"]*([^\"=]+)[\"]* => [\"]*([^\"]*)[\"]*", $itens[$i], $res);
                   if (isset($res))
                       $newNodeValue[trim($res[1])] = $res[2];
               }
           }
           // Object
           elseif (substr($nodeValue, 0, 2) == "O:")
               // Object serialized
               $newNodeValue = unserialize($nodeValue);
           // String
           elseif (!is_numeric($nodeValue))
                $newNodeValue = substr($nodeValue, 1, strlen($nodeValue) - 2);
           // Number
           else
                $newNodeValue = (($nodeValue == "") ? null : $nodeValue);
        }
        return $newNodeValue;
    }
};
?>
Arquivo: pTree_test.php
<?php
// Loading Abstract Data Type pTree
require_once "class.pTree.php";
// Creating tree
$tree = new pTree;
echo "<h1>Tree (Separator: \"/\")</h1>";
// Testing add with unlimited depth and value type
// add(nodeName [, nodeValue])
// PS.: Spaces are allowed, but converted to "_" char
$tree->add("child1");
$tree->add("child2", "value");
$tree->add("child3", array(1 => "value1", "item2" => 200));
$tree->add("child1/sub-child1", "valueTest");
$tree->add("child1/sub-child2", 200);
$tree->add("child1/sub-child3");
$tree->add("child4", "value");
$tree->add("child5");
$tree->add("child5/sub-child5.1");
$tree->add("child5/sub-child5.1/sub-child5.1.1");
$tree->add("child5/sub-child5.1/sub-child5.1.1/sub-child5.1.1.1");
$tree->add("child5/sub-child5.1/sub-child5.1.1/sub-child5.1.1.1/sub-child5.1.1.1.1", "Deep... but with value. =)");
// Test commenting a node (can be any node)
// comment(nodeName, nodeCommment)
// PS.: new line separator: \n
$tree->comment("child1/sub-child1", "Testing comments");
// Test retrieving a node
// get(nodeName)
echo "<b>Value of child2:</b> ".$tree->get("child2")."<br />";
echo "<b>Value of child1/sub-child2:</b> ".$tree->get("child1/sub-child2")."<br />";
// Converting tree into a Human readable text
echo "<h3>Displaying tree before removes</h3>";
echo "<pre>\n";
echo $tree->toString(1);
echo "</pre>";
// Test removing a node (can be any node). Sub-childs will be delete too
// remove(nodeName)
$tree->remove("child2");
$tree->remove("child5");
$tree->comment("child4", "Comments anywhere! =P");
// Retrieving content
$tree_content = $tree->toString(1);
// Displaying Tree after Node remove
echo "<h3>Displaying tree after removes</h3>";
echo "<pre>\n";
echo $tree_content;
echo "</pre>";
// Testing error handler (brackets test)
// Uncoment the next 2 lines to test
//$nTree = new pTree;
//$nTree->fromString(substr($tree_content, 0, strlen($tree_content) - 4));
// Reverse way... building new tree from a given text
$tree2 = new pTree(";");
$tree2->fromString($tree_content);
echo "<h1>Tree 2 (Separator: \";\")</h1>";
// Look at separator usage
// Updating content
$tree2->add("child1;sub-child3", "Now with value!");
// Commenting
$tree2->comment("child1;sub-child3", "Now I can put some comment here\nWith new line included!!!");
// Displaying tree2 node value, showing separator usage
echo "<b>Value of child1;sub-child3:</b> ".$tree2->get("child1;sub-child3")."<br />";
// Updating content
$tree2->add("child1;sub-child3", "Now with value!");
// Displaying tree
echo "<pre>\n";
echo $tree2->toString(1);
echo "</pre>";
// Testing other methods
echo "<h1>Testing Other Tools (using Tree 2)</h1>";
// isRoot(nodeName) => check if the node is root or not
echo "<b>child4</b> ".(($tree2->isRoot("child4")) ? "is" : "isn't")." root<br />";
// hasChilds(nodeName) => checks if nodeName has childNodes or not
echo "<b>child3</b> ".(($tree2->hasChilds("child3")) ? "has" : "hasn't")." childs<br />";
// hasValue(nodeName) => check if nodeName has a value or not
echo "<b>child1;sub-child1</b> ".(($tree2->hasValue("child1;sub-child1")) ? "has" : "hasn't")." value<br />";
// Displaying tree
echo "<h3>Displaying Object Tree 2 - Showing real pTree Structure</h3>";
echo "<pre>\n";
print_r($tree2);
echo "</pre>";
?>
Espero que gostem!!!


 
	 
					 
			
			
 
				
				
				 
			
			 
				
				
				 
			
			
 
				
				
				 
				
				
				

 
				
				
				 
				
				
				 
				
				
				 
				
				
				








