PHP:¿Cómo crear un árbol jerárquico a partir de una tabla en la DB?

De Foros del Web

Este método funciona para tablas con referencias a ellas mismas,como por ejemplo en un sistema que se desee mantener relaciones padre hijo sin usar tablas intermedias.

Ejemplo de estructura (sin ninguna DB en mente):

Tabla:

categoria

--cat_id //indice

--parent_id //indice al id del padre (en este caso una referencia a cat_id)

--nombre

--...más campos


Cabe destacar que con esta estructura se restringe a un solo padre por elemento, los nodos padre o raiz tendrán su campo "parent_id" en 0.

ahora bien para construir/imprimir un árbol con esos datos, la manera mas fácil es utilizar una función recursiva asi:

Código PHP:

/*
funcion generica
Parametros:
    $tabla     = Nombre de la tabla en la DB
    $id_field  = Nombre del campo llave de la tabla
    $show_data = Campo a mostrar en el arbol
    $link_field= Campo que establece la relacion padre hijo
    $parent       = padre actual
    $prefix    = string con un campo a mostrar en cada entrada del arbol
*/
function crearArbol($tabla,$id_field,$show_data,$link_field,$parent,$prefix){
    /*Armar query*/
    $sql='select * from '.$tabla.' where '.$link_field.'='.$parent;
 
    /*Asumiendo que se usa MySQL (se puede cambiar facilmente a otra db)*/
 
    $rs=@mysql_query($sql);
    if($rs){
           /*Recorrer todos las entradas */
           while($arr=mysql_fetch_array($rs)){
        /* Imprimir campo a mostrar*/
                echo($prefix.$arr[$show_data].'<br>');
 
        /* imprimir arbol the "hijos" de este elemento*/
                crearArbol($tabla,$id_field,$show_data,
                               $link_field,$arr[$id_field],$prefix.$prefix);
           }
    }    
}  

Código PHP:

/*
ahora, asumiendo que se tiene una tabla con una estructura
como la mencionada anteriormente se utilizaría así:
*/
 
crearArbol('categoria','cat_id','nombre','parent_id',0,'-'); 
 
/*
  lo cual tendrá un output algo así (dependiendo de los datos):
 
 -categoria1
 --categoria2
 -categoria3
 --categoria4
 ----categoria5 
 
*/  

Ahora, Cómo y por qué funciona:

Dadas las condiciones de la estructura de datos, donde el padre siempre es "0" para los elementos raiz, al llamar la función el query devuelve todos los elementos raiz en su primera llamada, al recorrer cada elemento, la función es llamada para imprimir todos los elementos hijos de este elemento, y así "recursivamente" hasta terminar con todos los elementos.

trabajaré en otra función para un escenario de muchos a muchos padre<->hijos, lo cual sería bastante parecido.



--Vaalegk 19 Oct 2005

Este artículo es parte de las FAQs de PHP y el Manual de PHP.

Herramientas personales