Benim kullandığım yapı aşağıda. Tek SQL sorgusuyla hiyerarşik sınırsız alt kategoriler oluşturabilirsiniz.

<?php

if (!($connection = mysql_connect('localhost', 'root', '')) || !mysql_select_db('cat', $connection))
	exit('Failed to connect to database...');

$tree = get_cat_tree();

echo '<pre>';
print_r($tree);
echo '</pre>';

function get_cat_tree()
{
	// Tüm kategorileri çek.
	$result = mysql_query('
		SELECT *
		FROM cats');
	$list = array();
	while ($row = mysql_fetch_assoc($result))
		$list[$row['id_cat']] = $row;
	mysql_free_result($result);

	// Her kategoriyi tek tek döngüye sokarak alt kategorileriyle eşleştir.
	$tree = array();
	foreach ($list as $id => $item)
	{
		if ($item['id_parent'] == 0)
		{
			$tree[$item['id_cat']] = $item;
			unset($list[$id]);

			find_sub_cats($list, $tree[$item['id_cat']]);
		}
	}

	return $tree;
}

function find_sub_cats(&$list, &$selected)
{
	foreach ($list as $id => $item)
	{
		if ($item['id_parent'] == $selected['id_cat'])
		{
			$selected['sub_cats'][$item['id_cat']] = $item;
			unset($list[$id]);
			find_sub_cats($list, $selected['sub_cats'][$item['id_cat']]);
		}
	}
}

?>
Alıntı
CREATE TABLE IF NOT EXISTS `cats` (
`id_cat` mediumint(8) NOT NULL AUTO_INCREMENT,
`cat_name` varchar(255) NOT NULL DEFAULT '',
`id_parent` mediumint(8) NOT NULL DEFAULT '0',
PRIMARY KEY (`id_cat`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;

INSERT INTO `cats` (`id_cat`, `cat_name`, `id_parent`) VALUES
(1, 'cat1', 0),
(2, 'cat2', 0),
(3, 'subcat1', 1),
(4, 'subcat2', 1),
(5, 'subcat3', 1),
(6, 'subcat4', 2),
(7, 'subcat5', 3),
(8, 'subcat6', 7),
(9, 'subcat7', 8);