Ho esaminato l'elenco di adiacenza e il modello di set annidato per trovare la soluzione di albero ottimale.Elenco di adiacenza rispetto al modello di serie nidificato
Fino ad ora ho pensato che uno dei principali vantaggi di Nested Set Model era che potevo usare una query SQL e del codice per ottenere un albero completo. Ma è complicato aggiornare/inserire i nodi e l'intero albero può facilmente essere corrotto.
Poi mi sono imbattuto in questi due messaggi:
Recursive categories with a single query?
http://www.sitepoint.com/forums/showthread.php?t=570360
Il seguente codice mi permette di utilizzare adiacenza List con una query SQL. Mi sembra che Adjacency List sia più facile da aggiornare e meno probabile che corrompa l'intero albero.
Cosa ne pensi di questo codice?
generare un array multidimensionale per riflettere la struttura ad albero
$nodeList = array();
$tree = array();
$query = mysql_query("SELECT id, title, page_parent FROM categories ORDER BY page_parent");
while($row = mysql_fetch_assoc($query)){
$nodeList[$row['id']] = array_merge($row, array('children' => array()));
}
mysql_free_result($query);
foreach($query AS $row){
$nodeList[$row['id']] = array_merge($row, array('children' => array()));
}
foreach ($nodeList as $nodeId => &$node) {
if (!$node['page_parent'] || !array_key_exists($node['page_parent'], $nodeList)) {
$tree[] = &$node;
} else {
$nodeList[$node['page_parent']]['children'][] = &$node;
}
}
unset($node);
unset($nodeList);
Preparare una lista non ordinata con nodi nidificati
function printMenu ($arrTreeToTraverse, $ext = '.html', $breadcrumb = '') {
// Pre loop stuff
echo "<ul class=\"sf-menu\">\r\n";
foreach ($arrTreeToTraverse as $objItem) {
// Stuff relevant to the item, before looping over its children
if ($objItem['page_parent'] != 0) {
$breadcrumb .= '/'.$objItem['uri'];
}
else
{
$breadcrumb .= $objItem['uri'];
}
if ($objItem['uri'] == 'index') {
echo '<li><a href="/">'.$objItem['title'].'</a>';
} else {
echo '<li><a href="'$_SERVER['SERVER_NAME'].'/'.$breadcrumb.$ext.'">'.$objItem['title'].'</a>';
}
if ($objItem['children']) {
echo "\r\n";
// Call the function again on the children
printMenu($objItem['children'], $ext, $breadcrumb);
}// if
// Extend breadcrumb if it is a child or
// reset breadcrumb if first level of tree
$parent = explode('/', $breadcrumb);
if ($objItem['page_parent'] != 0) {
$breadcrumb = $parent[0];
} else {
$breadcrumb = '';
}
echo "</li>\r\n";
}// foreach
// Post loop stuff
echo "</ul>\r\n";
}// function
printMenu($navigation, '.html');
Sembra ok tranne la riga 'foreach ($ query AS $) che non è necessaria e genererà un errore. – Fanis