मुझे एक उत्तर ऑनलाइन मिला और दूसरों को यह दिखाने के लिए कि यह कैसे किया जाता है, इस पृष्ठ पर प्रश्न को अपडेट किया।
अपडेट करें - समस्या हल हो गई
सबसे पहले, मुझे गलती से विश्वास हो गया था कि स्रोत तालिका (आसन्न-सूचियों के प्रारूप में से एक) को स्रोत नोड को शामिल करने के लिए बदलने की आवश्यकता है। यह मामला नहीं है। दूसरा, मुझे मिला एक वर्ग बिंग के माध्यम से जो चाल करता है। मैंने इसे PHP5 के लिए बदल दिया है और मूल लेखक के MySQL संबंधित बिट्स को मूल PHP में परिवर्तित कर दिया है। वह कुछ डीबी वर्ग का उपयोग कर रहा था। आप चाहें तो उन्हें बाद में अपने डेटाबेस एब्स्ट्रैक्शन क्लास में बदल सकते हैं।
जाहिर है, अगर आपकी "सोर्स टेबल" में अन्य कॉलम हैं जिन्हें आप नेस्टेड सेट टेबल पर ले जाना चाहते हैं, तो आपको नीचे दी गई क्लास में राइट मेथड को एडजस्ट करना होगा।
उम्मीद है कि यह भविष्य में किसी और को उन्हीं समस्याओं से बचाएगा।
<?php
/**
--
-- Table structure for table `adjacent_table`
--
DROP TABLE IF EXISTS `adjacent_table`;
CREATE TABLE IF NOT EXISTS `adjacent_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`father_id` int(11) DEFAULT NULL,
`category` varchar(128) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
--
-- Dumping data for table `adjacent_table`
--
INSERT INTO `adjacent_table` (`id`, `father_id`, `category`) VALUES
(1, 0, 'Books'),
(2, 0, 'CD''s'),
(3, 0, 'Magazines'),
(4, 1, 'Hard Cover'),
(5, 1, 'Large Format'),
(6, 3, 'Vintage');
--
-- Table structure for table `nested_table`
--
DROP TABLE IF EXISTS `nested_table`;
CREATE TABLE IF NOT EXISTS `nested_table` (
`lft` int(11) NOT NULL DEFAULT '0',
`rgt` int(11) DEFAULT NULL,
`id` int(11) DEFAULT NULL,
`category` varchar(128) DEFAULT NULL,
PRIMARY KEY (`lft`),
UNIQUE KEY `id` (`id`),
UNIQUE KEY `rgt` (`rgt`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
*/
/**
* @class tree_transformer
* @author Paul Houle, Matthew Toledo
* @created 2008-11-04
* @url http://gen5.info/q/2008/11/04/nested-sets-php-verb-objects-and-noun-objects/
*/
class tree_transformer
{
private $i_count;
private $a_link;
public function __construct($a_link)
{
if(!is_array($a_link)) throw new Exception("First parameter should be an array. Instead, it was type '".gettype($a_link)."'");
$this->i_count = 1;
$this->a_link= $a_link;
}
public function traverse($i_id)
{
$i_lft = $this->i_count;
$this->i_count++;
$a_kid = $this->get_children($i_id);
if ($a_kid)
{
foreach($a_kid as $a_child)
{
$this->traverse($a_child);
}
}
$i_rgt=$this->i_count;
$this->i_count++;
$this->write($i_lft,$i_rgt,$i_id);
}
private function get_children($i_id)
{
return $this->a_link[$i_id];
}
private function write($i_lft,$i_rgt,$i_id)
{
// fetch the source column
$s_query = "SELECT * FROM `adjacent_table` WHERE `id` = '".$i_id."'";
if (!$i_result = mysql_query($s_query))
{
echo "<pre>$s_query</pre>\n";
throw new Exception(mysql_error());
}
$a_source = array();
if (mysql_num_rows($i_result))
{
$a_source = mysql_fetch_assoc($i_result);
}
// root node? label it unless already labeled in source table
if (1 == $i_lft && empty($a_source['category']))
{
$a_source['category'] = 'ROOT';
}
// insert into the new nested tree table
// use mysql_real_escape_string because one value "CD's" has a single '
$s_query = "
INSERT INTO `nested_table`
(`id`,`lft`,`rgt`,`category`)
VALUES (
'".$i_id."',
'".$i_lft."',
'".$i_rgt."',
'".mysql_real_escape_string($a_source['category'])."'
)
";
if (!$i_result = mysql_query($s_query))
{
echo "<pre>$s_query</pre>\n";
throw new Exception(mysql_error());
}
else
{
// success: provide feedback
echo "<p>$s_query</p>\n";
}
}
}
mysql_connect('localhost','USER','PASSWORD') or die(mysql_error());
mysql_select_db('DATABASE') or die(mysql_error());
// build a complete copy of the adjacency table in ram
$s_query = "SELECT `id`,`father_id` FROM `adjacent_table`";
$i_result = mysql_query($s_query);
$a_rows = array();
while ($a_rows[] = mysql_fetch_assoc($i_result));
$a_link = array();
foreach($a_rows as $a_row)
{
$i_father_id = $a_row['father_id'];
$i_child_id = $a_row['id'];
if (!array_key_exists($i_father_id,$a_link))
{
$a_link[$i_father_id]=array();
}
$a_link[$i_father_id][]=$i_child_id;
}
$o_tree_transformer = new tree_transformer($a_link);
$o_tree_transformer->traverse(0);
?>
यहाँ आउटपुट है: