> Manuales > Taller de PHP

Esta clase se utiliza para ordenar matrices profundas que contengan unos elementos tales que dependan unos de otros.

El ejemplo típico serán categorías de artículos en una tienda virtual de uso general, pero se puede adaptar a otro tipo de datos que deban seguir la misma pauta.

El Punto de partida

Supongamos que tenemos una tienda virtual, en la que vamos a vender un poco de todo: ordenadores, libros, discos, películas, etc. Lógicamente, contaremos con una tabla de categorías en las que, posteriormente, encuadraremos los artículos de la tienda. La tabla de categorías contará, al menos, con los siguientes campos: Si recuperamos los datos de la tabla de categorías, y los almacenamos en una matriz bidimensional (comportamiento típico de las consultas de selección SQL), podríamos obtener una matriz como la que se representa, con unas cuantas categorías de ejemplo, a continuación:

CODIGO DE LA CATEGORÍA NOMBRE DE LA CATEGORÍA CODIGO DE LA CATEGORÍA DE LA QUE DEPENDE
1 Informática 0
5 Libros 0
2 Monitores 1
8 Teclados 1
3 Monitores CRT 2
4 Monitores TFT 2
7 Históricos 5
6 Novela 5
9 Con cable 8
10 Inalámbricos 8
11 Inalámbricos con ratón 8


Las categorías pueden proceder de la tabla en cualquier orden arbitrario, según se hayan ido grabando. Cada categoría cuenta con dos códigos, tal como hemos mencionado anteriormente: el suyo propio y el de aquella de la que depende jerárquicamente. Como el código de cada categoría es un campo auto numérico, que se empiezan a crear desde 1, se ha reservado el código 0 para aquellas categorías raíces, que no dependen de ninguna otra.

El problema

Partiendo de que recuperemos los datos de la tabla en una matriz de memoria, es necesario reorganizarlos en árbol. Por ejemplo, suponga que debemos mostrar las categorías en una lista de tipo SELECT, para que el administrador de la tienda elija en que categoría va a encuadrar un producto. La lista, tal como tenemos de momento la matriz, sería similar a la siguiente: Como ve, es poco práctica para el uso del administrador, y eso teniendo en cuenta las pocas categorías con las que estamos trabajando en nuestro ejemplo. Sería mucho más práctica si su aspecto fuera el siguiente: Como ve, la lista es mucho más clara y coherente, ya que los nombres aparecen modificados y ordenados para que se vea el mapa de categorías en la lista, a primer golpe de vista. Sin embargo, es necesario que al cambiar el orden de los elementos, se mantenga la paridad entre cada categoría y los códigos asociados a la misma, como es lógico. Tenga en cuenta, que si construimos un SELECT con la matriz, los nombres serán lo que se mostrará al administrador, y los códigos de cada categoría serán los VALUES de cada OPTION.


Por lo tanto, la matriz debe poder modificarse, de modo que quede así:

array(11) {
[0]=>
array(3) {
["codigoCategoria"]=>
string(1) "1"
["nombreCategoria"]=>
string(11) "Informática"
["dependeDeCodigoCategoria"]=>
string(1) "0"
}
[1]=>
array(3) {
["codigoCategoria"]=>
string(1) "2"
["nombreCategoria"]=>
string(23) "Informática " Monitores"
["dependeDeCodigoCategoria"]=>
string(1) "1"
}
[2]=>
array(3) {
["codigoCategoria"]=>
string(1) "3"
["nombreCategoria"]=>
string(39) "Informática " Monitores " Monitores CRT"
["dependeDeCodigoCategoria"]=>
string(1) "2"
}
[3]=>
array(3) {
["codigoCategoria"]=>
string(1) "4"
["nombreCategoria"]=>
string(39) "Informática " Monitores " Monitores TFT"
["dependeDeCodigoCategoria"]=>
string(1) "2"
}
[4]=>
array(3) {
["codigoCategoria"]=>
string(1) "8"
["nombreCategoria"]=>
string(22) "Informática " Teclados"
["dependeDeCodigoCategoria"]=>
string(1) "1"
}
[5]=>
array(3) {
["codigoCategoria"]=>
string(1) "9"
["nombreCategoria"]=>
string(34) "Informática " Teclados " Con cable"
["dependeDeCodigoCategoria"]=>
string(1) "8"
}
[6]=>
array(3) {
["codigoCategoria"]=>
string(2) "10"
["nombreCategoria"]=>
string(37) "Informática " Teclados " Inalámbricos"
["dependeDeCodigoCategoria"]=>
string(1) "8"
}
[7]=>
array(3) {
["codigoCategoria"]=>
string(2) "11"
["nombreCategoria"]=>
string(47) "Informática " Teclados " Inalámbricos con ratón"
["dependeDeCodigoCategoria"]=>
string(1) "8"
}
[8]=>
array(3) {
["codigoCategoria"]=>
string(1) "5"
["nombreCategoria"]=>
string(6) "Libros"
["dependeDeCodigoCategoria"]=>
string(1) "0"
}
[9]=>
array(3) {
["codigoCategoria"]=>
string(1) "7"
["nombreCategoria"]=>
string(19) "Libros " Históricos"
["dependeDeCodigoCategoria"]=>
string(1) "5"
}
[10]=>
array(3) {
["codigoCategoria"]=>
string(1) "6"
["nombreCategoria"]=>
string(15) "Libros " Novela"
["dependeDeCodigoCategoria"]=>
string(1) "5"
}
}


La solución

La clase class.ordenarCategorias.php nos proporciona una forma muy simple de obtener este resultado. Para usarla, debemos empezar, lógicamente, por incluirla en nuestro script (con PHP 5 podemos evitar la inclusión específica si lo deseamos, mediante __autoload(), pero eso es otra cuestión).

include ("class.ordenarCategorias.php");

A continuación, deberemos crear un objeto de la clase, así:

$matriz = new ordenarCategorias();

En este ejemplo, al objeto le hemos llamado $matriz.

Lo siguiente es cargar en la propiedad matriz del objeto la matriz original de la que partiremos, que está sin ordenar, tal como vemos a continuación:

$matriz->matriz = $matrizOriginal;

A continuación, debemos indicar, en la propiedad idItem cual es la clave asociativa de la matriz que contiene el código de cada categoría, así:

$matriz->idItem = "codigoCategoria";

El siguiente paso es cargar, en la propiedad nombreItem, el nombre de la clave asociativa que contiene el nombre de cada categoría, como vemos aquí:

$matriz->nombreItem = "nombreCategoria";

En la propiedad idPadre colocaremos la clave asociativa que usemos para identificar el código del que depende cada categoría, así:

$matriz->idPadre = "dependeDeCodigoCategoria";

Por último, usaremos el método crearMapa(), del objeto, que nos devuelve la matriz modificada y ordenada según nuestros deseos:

$matrizOrdenada = $matriz->crearMapa();

Como puedes ver, el uso no puede ser más sencillo.

Como complemento, aclarar que si cada categoría en la matriz original tiene más datos asociados, estos no sufrirán ningún efecto colateral.

Sunflower

Manual