Publicado nuevamente por Joy Murakami, he leído este artículo antes y está explicado con bastante claridad.
Nos encontraremos con este problema en muchos lugares, como clasificación de productos, foros estructurados en árbol de varios niveles, listas de correo, etc.: ¿Cómo almacenar datos estructurados de varios niveles?
En las aplicaciones PHP, el almacenamiento de datos backend suele ser una base de datos relacional, que puede guardar grandes cantidades de datos y proporcionar servicios eficientes de recuperación y actualización de datos. Sin embargo, la forma básica de datos relacionales es una tabla entrecruzada, que es una estructura plana. Si desea almacenar una estructura de árbol de varios niveles en una base de datos relacional, debe realizar un trabajo de traducción razonable. A continuación, comentaré con ustedes lo que he visto y oído y algunas experiencias prácticas.
Básicamente, existen dos métodos de diseño comunes para almacenar datos jerárquicos en bases de datos planas:
modelo de lista de adyacencia
Algoritmo de recorrido del árbol de preorden modificado
No soy experto en informática y no he aprendido nada sobre estructuras de datos, así que traduje estos dos nombres literalmente. Avíseme si me equivoco.
Estas dos cosas pueden parecer aterradoras, pero en realidad son muy fáciles de entender. Aquí utilizo un directorio de alimentos simple como datos de ejemplo. Nuestra estructura de datos es así:
Alimento
|
|---Fruta
|
|---Rojo
|
|--Cereza
|
|---Amarillo
|
|--Plátano
|
|---Carne
|
|--Carne de res
|
|--Cerdo
Para cuidar a aquellos entusiastas de PHP que tienen un lío de
comida inglesa: Comida
fruta: fruta
rojo: rojo
cereza: cereza
Amarillo: amarillo
plátano: plátano
Carne: Carne
Carne de res: carne de res
Cerdo:
el modelo de lista de adyacencia
de cerdoes un modelo que usamos con frecuencia y se ha introducido en muchos tutoriales y libros. Describimos toda la estructura del árbol a través de una tabla plana agregando un atributo principal a cada nodo para representar el nodo principal de este nodo. Según este principio, los datos del ejemplo se pueden transformar en la siguiente tabla:
+-----------------------+
| padre | nombre |
+-----------------------+
| Comida |
Alimentos | Frutas |
| Fruta | Verde |
| Verde | Pera |
| Fruta | Rojo |
| Rojo | Cereza |
| Fruta | Amarillo |
| Amarillo | Plátano |
| Comida | Carne |
Carne |
| Carne de cerdo |
+-----------------------+
Vemos que Pear es un nodo hijo de Green y Green es un nodo hijo de Fruit. El nodo raíz 'Comida' no tiene ningún nodo principal. Para describir este problema de forma sencilla, en este ejemplo solo se utiliza el nombre para representar un registro. En una base de datos real, necesita usar una identificación numérica para identificar cada nodo. La estructura de la tabla de la base de datos probablemente debería verse así: id, parent_id, nombre, descripción. Con una tabla de este tipo podemos guardar toda la estructura de árbol de varios niveles a través de la base de datos.
Mostrar un árbol de varios niveles Si necesitamos mostrar una estructura de varios niveles, necesitamos una función recursiva.
<?php
// $parent es el padre de los niños que queremos ver
// $level aumenta cuando profundizamos en el árbol,
// se usa para mostrar una bonita
función de árbol con sangría display_children($parent, $level)
{
// Obtener todos los nodos secundarios de un nodo padre $parent
$resultado = mysql_query('SELECCIONAR nombre DEL árbol '.
'WHERE parent="'.$parent.'";');
// Muestra cada nodo secundario.
mientras ($fila = mysql_fetch_array($resultado))
{
//Sangra el nombre del nodo
echo str_repeat(' ',$level).$row['name']."n";
// Llame a esta función nuevamente para mostrar los nodos secundarios del nodo secundario
display_children($row['name'], $level+ 1);
}
}
?>
El uso de esta función en el nodo raíz (Comida) de toda la estructura puede imprimir la estructura de árbol de varios niveles completa. Dado que Comida es el nodo raíz y su nodo principal está vacío, llame a: display_children('',0). mostrará el contenido de todo el árbol:
Alimento
Fruta
Rojo
Cereza
Amarillo
Banana
Carne
Carne de res
Cerdo
Si solo desea mostrar una parte de toda la estructura, como la parte de la fruta, puede llamarla así:
display_children('Fruit',0);
Casi usando el mismo método, podemos conocer la ruta desde el nodo raíz. a cualquier nodo. Por ejemplo, la ruta de Cherry es "Comida > Fruta > Rojo". Para obtener dicha ruta, debemos comenzar desde el nivel más profundo "Cherry", consultar para obtener su nodo principal "Red" y agregarlo a la ruta, y luego consultamos el nodo principal de Red y lo agregamos a la ruta. , y así sucesivamente hasta el nivel superior "Comida"
<?php
// $nodo es el nodo más profundo
función get_path($nodo)
{
// Consulta el nodo padre de este nodo
$resultado = mysql_query('SELECCIONAR padre DEL árbol '.
'DONDE nombre="'.$nodo.'";');
$row = mysql_fetch_array($resultado);
// Usa una matriz para guardar la ruta
$path = array();
// Si no es el nodo raíz, continúa consultando hacia arriba
// (El nodo raíz no tiene nodo padre)
si ($fila['padre']!='')
{
// la última parte de la ruta a $nodo, es el nombre
// del padre de $nodo
$path[] = $row['parent']
// debemos agregar la ruta al padre de este nodo
// al camino
$ruta = array_merge(get_path($fila['padre']), $ruta);
}
// devuelve la ruta
devolver $ruta;
}
?>
Si usa esta función para "Cherry": print_r(get_path('Cherry')), obtendrá una matriz como esta:
Formación
(
[0] => Comida
[1] => Fruta
[2] => Rojo
)
Cómo imprimirlo en el formato que desees depende de ti.
Desventajas: este método es muy simple, fácil de entender y fácil de usar. Pero hay algunas desventajas. Principalmente porque la velocidad de ejecución es muy lenta, porque cada nodo requiere una consulta de la base de datos y, cuando la cantidad de datos es grande, se requieren muchas consultas para completar un árbol. Además, debido a la necesidad de operaciones recursivas, cada nivel de recursividad necesita ocupar algo de memoria, por lo que la eficiencia de utilización del espacio es relativamente baja.
Ahora echemos un vistazo a otro método que no utiliza cálculos recursivos y es más rápido. Este es el algoritmo transversal del árbol de preorden modificado. Es posible que tenga menos exposición a este método y no es como el anterior cuando lo usa. La primera vez, el método es fácil de entender, pero debido a que este método no utiliza algoritmos de consulta recursivos, tiene una mayor eficiencia de consulta.
Primero dibujamos los datos de varios niveles en papel de la siguiente manera, escribimos 1 en el lado izquierdo del nodo raíz Comida, luego continuamos hacia abajo en el árbol, escribimos 2 en el lado izquierdo de Fruta y luego continuamos moviéndonos a lo largo de todo el árbol. Los bordes etiquetan cada nodo con números a la izquierda y a la derecha. El último número es el 18 marcado a la derecha de Comida. En la imagen de abajo puedes ver toda la estructura de varios niveles marcada con números. (¿No entiendes? Señala los números con los dedos y cuenta del 1 al 18 y lo entenderás. Si aún no entiendes, vuelve a contar y ten cuidado al mover los dedos).
Estos números indican la relación entre cada nodo. Los números de "Rojo" son 3 y 6, que son los nodos descendientes de "Alimentos" 1-18. De manera similar, podemos ver que todos los nodos con un valor izquierdo mayor que 2 y un valor derecho menor que 11 son descendientes de "Fruit" 2-11.
1 comida 18
|
+-----------------------------------------------+
|
2 Fruta 11 12 Carne 17
|
+---------------------+ +---------------------+
|
3 Rojo 6 7 Amarillo 10 13 Res 14 15 Cerdo 16
|
4 Cereza 5 8 Plátano 9
De esta manera, toda la estructura del árbol se puede almacenar en la base de datos a través de los valores izquierdo y derecho. Antes de continuar, echemos un vistazo a la siguiente tabla de datos compilados.
+-----------------------+-----+-----+
| padre | nombre | lft |
+-----------------------+-----+-----+
| 18 |
| Comida | 2 | 11 |
| Fruta | Rojo | 3 |
| Rojo | Cereza 4 |
| Fruta | Amarillo | 7 |
| Amarillo | Plátano | 8 |
| Comida | Carne | 12 |
| Carne de res | 13 |
| Carne de cerdo | 15 |
+-----------------------+-----+-----+
Nota: Dado que "izquierda" y "derecha" tienen significados especiales en SQL, debemos usar "lft" y "rgt" para representar los campos izquierdo y derecho. Además, el campo "principal" ya no es necesario en esta estructura para representar la estructura de árbol. En otras palabras, la siguiente estructura de tabla es suficiente.
+------------+-----+-----+
| nombre |
+------------+-----+-----+
| Comida 1 | 18 |
| fruta | 2 | 11 |
| Rojo | 3 | 6 |
| cereza 4 | 5 |
| Amarillo | 7 | 10 |
| Plátano | 8 | 9 |
| Carne | 12 | 17 |
| Carne de res | 13 |
| Cerdo | 15 | 16 |
+------------+-----+-----+
Bien, ahora podemos obtener datos de la base de datos. Por ejemplo, si necesitamos obtener todos los nodos bajo el elemento "Fruta", podemos escribir la declaración de consulta de esta manera: SELECT * FROM tree WHERE lft BETWEEN 2 AND 11; La consulta obtuvo los siguientes resultados.
+------------+-----+-----+
| nombre |
+------------+-----+-----+
| fruta | 2 | 11 |
| Rojo | 3 | 6 |
| cereza 4 | 5 |
| Amarillo | 7 | 10 |
| Plátano | 8 | 9 |
+------------+-----+-----+
Mira, puedes obtener todos estos nodos con una sola consulta. Para poder mostrar toda la estructura de árbol como la función recursiva anterior, también necesitamos ordenar dicha consulta. Ordene por el valor l del nodo:
SELECCIONE * DEL árbol DONDE lft ENTRE 2 Y 11 ORDEN POR lft ASC;
La pregunta restante es cómo mostrar la sangría jerárquica.
<?php
función display_tree($raíz)
{
//Obtiene los valores izquierdo y derecho del nodo raíz
$resultado = mysql_query('SELECT lft, rgt FROM tree '.'WHERE name="'.$root.'";');
$row = mysql_fetch_array($resultado);
// Prepara una pila de valores vacía
$right = array();
// Obtiene todos los nodos descendientes del punto raíz
$resultado = mysql_query('SELECCIONAR nombre, lft, rgt FROM árbol '.
'DONDE queda ENTRE '.$fila['lft']'.
$fila['rgt'].' ORDER BY lft ASC;'
// Muestra cada fila
mientras ($fila = mysql_fetch_array($resultado))
{
// solo revisa la pila si hay una
si (cuenta($derecha)>0)
{
// Comprobamos si debemos sacar el nodo de la pila
mientras ($derecha[cuenta($derecha)-1]<$fila['rgt'])
{
array_pop($derecha);
}
}
// Sangra el nombre del nodo.
echo str_repeat(' ',count($right)).$row['name']."n"
// Agrega este nodo a la pila
$derecha[] = $fila['rgt'];
}
}
?>
Si ejecuta la función anterior obtendrá el mismo resultado que la función recursiva. Es solo que nuestra nueva función puede ser más rápida porque solo hay 2 consultas a la base de datos. Es más fácil conocer la ruta de un nodo. Si queremos conocer la ruta de Cherry, usamos sus valores izquierdo y derecho 4 y 5 para realizar una consulta.
SELECCIONE el nombre DEL árbol DONDE lft < 4 Y rgt > 5 ORDEN POR lft ASC;
Esto le dará el siguiente resultado:
+----------------+
| nombre |
+----------------+
Comida |
Fruta |
| Rojo |
+----------------+
Entonces, ¿cuántos nodos descendientes tiene un determinado nodo? Es muy simple, el número total de descendientes = (rvalor - valor izquierdo - 1)/2 descendientes = (derecha - izquierda - 1) / 2 ¿No lo crees? Haz los cálculos tú mismo. Usando esta fórmula simple, podemos calcular rápidamente que el nodo "Fruit 2-11" tiene 4 nodos descendientes, mientras que el nodo "Banana 8-9" no tiene nodos descendientes, lo que significa que no es un nodo padre.
Increíble, ¿verdad? Aunque he usado este método muchas veces, todavía me siento increíble cada vez que lo hago.
De hecho, este es un buen método, pero ¿hay alguna forma de ayudarnos a crear una tabla de datos con valores izquierdo y derecho? Aquí hay otra función que presentarle. Esta función puede convertir automáticamente la tabla con nombre y estructuras principales en una tabla de datos con valores izquierdo y derecho.
<?php
función reconstruir_árbol($padre, $izquierda) {
// el valor derecho de este nodo es el valor izquierdo + 1
$right = $left+1
// obtiene todos los hijos de este nodo
$resultado = mysql_query('SELECCIONAR nombre DEL árbol '.
'DONDE padre="'.$padre.'";');
mientras ($fila = mysql_fetch_array($resultado)) {
// ejecución recursiva de esta función para cada
// hijo de este nodo
// $right es el valor correcto actual, que es
// incrementado por la función reconstruir_árbol
$derecha = reconstruir_árbol($fila['nombre'], $derecha);
}
// tenemos el valor izquierdo y ahora que hemos procesado
// los hijos de este nodo también conocemos el valor correcto
mysql_query('ACTUALIZAR árbol SET lft='.$left.', rgt='.
$right.' WHERE name="'.$parent.'";');
// devuelve el valor correcto de este nodo + 1
devolver $derecha+1;
}
?>
Por supuesto, esta función es una función recursiva. Necesitamos ejecutar esta función desde el nodo raíz para reconstruir un árbol con valores izquierdo y derecho
rebuild_tree('Food',1);
Esta función parece un poco complicada, pero su función es la misma que numerar manualmente la tabla, que consiste en convertir la estructura tridimensional multicapa en una tabla de datos con valores izquierdo y derecho.
Entonces, ¿cómo agregamos, actualizamos y eliminamos un nodo para dicha estructura? Generalmente, hay dos formas de agregar un nodo:
conservar el nombre original y la estructura principal, usar el método anterior para agregar datos a los datos y usar la función reconstruir_árbol para renumerar toda la estructura después de agregar cada dato.
Un enfoque más eficaz es cambiar todos los valores a la derecha del nuevo nodo. Por ejemplo: queremos agregar una nueva fruta "Fresa" que se convertirá en el último nodo hijo del nodo "Rojo". Primero necesitamos hacerle algo de espacio. El valor derecho de "Rojo" debe cambiarse de 6 a 8, y el valor izquierdo y derecho de "Amarillo 7-10" debe cambiarse a 9-12. Por analogía, podemos saber que si desea dejar espacio para nuevos valores, debe agregar 2 a todos los nodos con valores izquierdo y derecho mayores que 5 (5 es el valor derecho del último nodo secundario de "Rojo" ). Entonces realizamos operaciones de base de datos como esta:
ACTUALIZAR árbol SET rgt=rgt+2 WHERE rgt>5;
ACTUALIZAR árbol SET lft=lft+2 WHERE lft>5;
Esto libera espacio para el valor recién insertado. Ahora puede crear un nuevo nodo de datos en el espacio liberado. Sus valores izquierdo y derecho son 6 y 7 respectivamente
. 'Fresa';
¡Hagamos otra consulta y veamos! ¿Qué tal? Pronto.
Bien, ahora puedes diseñar tu estructura de base de datos multinivel de dos maneras diferentes. El método que utilices depende completamente de tu criterio personal, pero para estructuras con muchos niveles y un gran número, prefiero el segundo método. El primer método es más sencillo si el volumen de consultas es pequeño pero los datos deben agregarse y actualizarse con frecuencia.
Además, si la base de datos lo admite, también puede escribir reconstruir_tree () y la operación de liberación de espacio como una función de activación en el lado de la base de datos, y ejecutarla automáticamente durante la inserción y actualización. Esto puede lograr una mejor eficiencia operativa, y puede hacerlo. Agregar nuevos nodos será más sencillo.
Método recursivo de clase
Publicado por invitado el 31 de mayo de 2004 - 9:18 am.
Escribí un programa usando un método cuasi recursivo, que no es exactamente el mismo que la recursión en el artículo, y me estoy preparando para trasplantarlo a xoops:
http://dev.xoops.org/modules/xfmod/project/?ulink
ha experimentado un desbordamiento de memoria, pero planeo continuar usando el método recursivo. Solo necesito seguir mejorando,
espero tener la oportunidad de discutir
.cms contigo.
» responder a este comentario
¿O una comparación de los dos métodos?
Publicado por invitado el 17 de marzo de 2004 - 8:30 p.m.
Estudié este artículo detenidamente y sentí que era muy beneficioso, pero luego lo pensé de nuevo y sentí que había un problema (para no recordar, llamo al modo de directorio adyacente método recursivo y al recorrido de clasificación previa Algoritmo de árbol que llamo método de árbol de clasificación previa):
1. La mayor diferencia entre los dos métodos es que la recursividad requiere el uso de una pila al realizar consultas, mientras que el árbol de clasificación previa requiere la mitad de los nodos (con referencia a la segunda mitad de el nodo insertado) al actualizar los nodos de actualizaciones. Aunque también dijo que si hay muchos nodos y actualizaciones frecuentes, la eficiencia del árbol preordenado se reducirá y la recursividad será mejor. Si hay muchos niveles de nodos, en primer lugar, la recursividad provocará un desbordamiento de la pila. además, la recursividad en sí no es muy eficiente. Además, cada nivel de recursividad requiere operar la base de datos, el efecto general no será ideal. Mi enfoque actual es sacar todos los datos a la vez y luego realizar operaciones recursivas en la matriz, lo cual será mejor si se puede mejorar aún más, se puede agregar un nodo raíz ROOT a cada fila de registros (actualmente, solo; se registran los nodos principales adyacentes), por lo que la eficiencia al buscar en el árbol de ramas será mayor y también será muy conveniente al actualizar el árbol, lo que debería ser una mejor manera.
2. Mejore el método recursivo. En el artículo, al calcular los valores izquierdo y derecho de los nodos del árbol preclasificados, en realidad se utiliza un método transversal. La pila se reemplaza por una matriz y se usa push y pop. se implementan manualmente; si se hace referencia a este método en el algoritmo recursivo, si usa una matriz en lugar de una pila al realizar la recursividad, también puede mejorar la eficiencia de la recursividad.
3. Si se tiene en cuenta la concurrencia, especialmente al actualizar el árbol, el método de actualizar la información de los nodos en un área grande del árbol preclasificado requiere una atención especial al uso de mecanismos de bloqueo y transacción para garantizar. consistencia de los datos.
4. En el caso de múltiples nodos raíz o múltiples nodos principales, en este caso, obviamente no es un árbol binario estándar o un árbol de múltiples bifurcaciones. El algoritmo del árbol preordenado debe mejorarse en gran medida para adaptarse, y el método recursivo. se aplica libremente, por lo que en este caso la recursividad es más adaptable. Por supuesto, esto se debe a que el método recursivo es una forma de lista vinculada. Los árboles y los gráficos se pueden expresar mediante listas vinculadas y, por supuesto, es muy adaptable.
5. Intuitivo Si observa directamente los datos almacenados en la base de datos sin la operación del programa, es obvio que los datos almacenados en el modo recursivo son más intuitivos, mientras que los datos en el árbol preordenado son difíciles de leer directamente (para jerárquicos). relaciones). Esto es importante en el intercambio de datos.
En términos generales, personalmente prefiero usar métodos recursivos, pero siempre me ha preocupado el impacto de la recursividad en la eficiencia. Afortunadamente, no he estado expuesto a niveles de clasificación a gran escala. Usar matrices en lugar de pilas sería una mejor mejora. método. El árbol preordenado es un método eficaz para resolver árboles simples. Una vez que se acostumbre a él, debería ser muy bueno, especialmente su búsqueda inversa desde el nodo hoja hasta el nodo raíz es muy conveniente.
lobo
www.fwolf.com
» responder a este comentario
Muy feliz de ver tu respuesta.
Publicado por shuke el 18 de marzo de 2004 - 5:47 am.
Me alegra mucho que hayas leído este artículo con tanta atención. En realidad, este artículo se publicó originalmente en sitepoint.com. Lo traduje con la esperanza de presentar algunos métodos a los amigos que quieran comenzar. Tu método también es muy bueno, lo probaré si tengo la oportunidad. (Si está interesado, ¿por qué no escribe su método y código de implementación específico como un tutorial basado en el ejemplo anterior, para que todos puedan imitarlo con ejemplos más prácticos?) Si tiene preguntas sobre cómo guardar estructuras multinivel en la base de datos. Si está interesado en la investigación, aquí hay otros dos buenos enlaces que pueden usarse como referencia:
Al presentar los cuatro métodos comunes de consulta única y script de clasificación de matrices, creo que su script debe ser mejor que este.
Además, vi que también usas drupal. También tiene una función avanzada llamada sistema de autenticación de usuarios distribuidos. Siempre que te registres en cualquier sitio drupal, puedes iniciar sesión para acceder a otros sitios drupal. Bastante interesante.
¡Los mejores deseos!
» responder a este comentario
Se ha implementado la construcción de árboles mediante bucles.
Publicado por invitado el 25 de marzo de 2004 - 22:10 horas.
Leí toda la información que proporcionaste la última vez, pero para ser honesto, no hay muchas cosas nuevas en el primer artículo. Tal vez no lo entendí muy bien. El segundo artículo en realidad fue escrito en PHP3 y la estructura del programa. no se detalló. Mira, se utilizan demasiadas intersecciones de funciones.
Dio la casualidad de que necesitaba usar roles de usuario jerárquicos en un sistema, así que escribí el recorrido basado en la idea de una matriz. No tuve tiempo de resolverlo, así que lo pondré aquí. Para que pueda echarle un vistazo, la base de datos es ADODB y el programa se extrae directamente del sistema. Espero que se pueda describir claramente. Utiliza principalmente las potentes operaciones de matriz de PHP y utiliza bucles para realizar recursividad. El comentario es un método similar, pero el momento de procesar los resultados es diferente.
<?php
/**
* Mostrar lista
* @acceso público
*/
función DispList()
{
//Modo de visualización sin sangría
// $this->mIsDispListIndex = verdadero;
// echo('<p align="right"><a href="?action=new&part=role">Agregar nuevo rol</a> </p>'); _fcksavedurl=""?action=new&part=role ">Agregar nuevo rol</a> </p>');"
//
// $this->mListTitle = 'Lista de roles de usuario';
// $this->SetDataOption('lista');
//
// $this->SetQueryTable( array($this->mTableUserRole) );
//
// //orden de consulta
// $this->SetQueryOrder( 'asc', $this->mTableUserRole, 'sequence' );
//
// $this->Query('lista');
// parent::DispList();
// // Otro método de visualización, utilizando una matriz como pila, A: Guarde el rol al presionar en la pila y elimine la fuente después de presionar.
// $this->CheckProperty('mrDb');
// $this->CheckProperty('mrSql');
// $this->mrSql->Select('rol, título, padre');
// $this->mrSql->From($this->mTableUserRole);
// $this->mrSql->Orderby('padre, secuencia');
// $this->mRs = $this->mrDb->Execute($this->mrSql->Sql());
// si (0 < cuenta($this->mRs))
// {
// $fuente = & $this->mRs->GetArray() //Índice numérico
// $pila = matriz(''); //pila
// $stacki = array(-1); // Corresponde a la pila, registra el nivel de los datos en la pila en el árbol
// $objetivo = matriz();
// mientras (0 < cuenta($pila))
// {
// $elemento = array_shift($pila);
// $lev = array_shift($stacki);
// si (!vacío($artículo))
// {
// //Coloque los datos procesados en la matriz de destino aquí
// array_push($objetivo, str_repeat(' ', $lev). $artículo);
// //$s1 = str_repeat(' ', $lev) $artículo;
// }
// $del = array(); //Nodo a eliminar de $source
// $ar = array(); //Nodos que deben agregarse a la pila
// foreach ($fuente como $clave=>$val)
// {
// //Buscar nodos secundarios coincidentes
// si (vacío($artículo))
// {
// $buscar = vacío($fuente[$clave]['padre']);
// }
//demás
// {
// $buscar = ($item == $fuente[$clave]['padre']);
// }
// si ($buscar)
// {
// array_unshift($ar, $fuente[$clave]['rol']);
// $del[] = $clave;
// }
// }
// foreach ($ar como $val)
// {
//array_unshift($pila, $val);
//array_unshift($stacki, $lev + 1);
// }
// foreach ($del como $val)
// {
// unset($fuente[$val]);
// }
// echo(implode(', ', $pila) . '<br />' . implode(', ', $pilaki) . '<br />' . implode(', ', $objetivo) . '< br /><br />');
// }
//debug_array();
// }
//demás
// {
// echo('<center>No se recuperaron datos</center>');
// }
// Otro método de visualización, usando una matriz como pila, B: guarde el índice de la matriz al empujar la pila, sáquelo de la pila y luego elimine la fuente después de su uso.
$this->CheckProperty('mrDb');
$this->CheckProperty('mrSql');
$this->mrSql->Select('rol, título, padre');
$this->mrSql->From($this->mTableUserRole);
$this->mrSql->Orderby('padre, secuencia');
$this->mRs = $this->mrDb->Execute($this->mrSql->Sql());
if (!empty($this->mRs) && !$this->mRs->EOF)
{
$fuente = & $this->mRs->GetArray() //índice numérico
$pila = matriz(-1); //pila
$stacki = array(-1); // Corresponde a la pila, registra el nivel de los datos en la pila en el árbol
$objetivo = matriz();
mientras (0 <cuenta($pila))
{
$elemento = array_shift($pila);
$lev = array_shift($stacki);
si (-1 != $artículo)
{
//Coloca aquí los datos procesados en la matriz de destino
$s1 = str_repeat(' ', $lev) '<a href="?action=disp&part=role&role=' . $fuente[$item]['rol'] . '">' . ['título'] '</a>';
$s2 = '<a href="?action=edit&part=role&role=' . $source[$item]['role'] . '">Editar</a> <a href="?action=delete&part=role&role= ' . $fuente[$item]['rol'] '">Eliminar</a>';
array_push($objetivo, matriz($s1, $s2));
}
$del = array(); //Nodo a eliminar de $source
$ar = array(); //Nodos que deben agregarse a la pila
foreach ($fuente como $clave=>$val)
{
//Buscar nodos secundarios coincidentes
si (-1 == $artículo)
{
$buscar = vacío($fuente[$clave]['padre']);
}
demás
{
$buscar = ($fuente[$artículo]['rol'] == $fuente[$clave]['padre']);
}
si ($ encontrar)
{
array_unshift($ar, $clave);
}
}
foreach ($ar como $val)
{
array_unshift($pila, $val);
array_unshift($stacki, $lev + 1);
}
//Eliminar de la fuente
unset($fuente[$artículo]);
//echo(implode(', ', $pila) . '<br />' . implode(', ', $pilaki) . '<br />' . implode(', ', $objetivo) . '< br /><br />');
}
//Producción
echo('<p align="right"><a href="?action=new&part=role">Agregar nuevo rol</a> </p>');
array_unshift($objetivo, array('rol', 'operación'));
$this->CheckProperty('mrLt');
$this->mrLt->SetData($objetivo);
$this->mrLt->mListTitle = 'Lista de roles de usuario';
$this->mrLt->mIsDispIndex = falso;
$this->mrLt->Disp();
}
demás
{
echo('<center>No se recuperaron datos</center>');
}
} // fin de la función DispList
?>