Cómo crear árbol de categorías con PHP PDO y MySQL?

En este tutorial usted aprenderá cómo crear categoría de árbol con PHP (PDO) y MySQL. A continuación, puede utilizar esta categoría de árbol para mostrar en un cuadro desplegable o lista.

Creamos una tabla en MySQL con las columnas principales y secunadarias.

CREATE TABLE IF NOT EXISTS `categorias` (
  `id_categoria` int(11) NOT NULL AUTO_INCREMENT,
  `nombre` varchar(255) NOT NULL,
  `id_padre` int(11) NOT NULL,
  PRIMARY KEY (`id_categoria`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Insertamos algunos registros como ejemplo. Las columnas padres con valor cero denota la base de la categoría.

INSERT INTO `categorias` (`id_categoria`, `nombre`, `id_padre`) VALUES
(1, 'Hardware', 0),
(2, 'Software', 0),
(3, 'Movies', 0),
(4, 'Clothes', 0),
(5, 'Printers', 1),
(6, 'Monitors', 1),
(7, 'Inkjet printers', 5),
(8, 'Laserjet Printers', 5),
(9, 'LCD monitors', 6),
(10, 'TFT monitors', 6),
(11, 'Antivirus', 2),
(12, 'Action movies', 3),
(13, 'Comedy Movies', 3),
(14, 'Romantic movie', 3),
(15, 'Thriller Movies', 3),
(16, 'Mens', 4),
(17, 'Womens', 4),
(18, 'Shirts', 16),
(19, 'T-shirts', 16),
(20, 'Shirts', 16),
(21, 'Jeans', 16),
(22, 'Accessories', 16),
(23, 'Tees', 17),
(24, 'Skirts', 17),
(25, 'Leggins', 17),
(26, 'Jeans', 17),
(27, 'Accessories', 17),
(28, 'Watches', 22),
(29, 'Tie', 22),
(30, 'cufflinks', 22),
(31, 'Earrings', 27),
(32, 'Bracelets', 27),
(33, 'Necklaces', 27),
(34, 'Pendants', 27);

Creamos la conexion a la base de datos.
Creamos un archivo llamado conexion.php donde haremos la conexión a la base de datos.

<?php 
    $root = 'root';
    $password = '';
    $host = 'localhost';
    $dbname = 'db';
    $parametros = array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'");
    try
    {
        $connection = new PDO("mysql:host=$host;dbname=$dbname;", $root, $password, $parametros);
    }
    catch(PDOException $e)
    {
        echo $e -> getMessage(); 
    }
?>

Creando árbol de categorías utilizando la recursividad.
De modo que la base de datos está todo listo, crear una función de PHP para obtener de forma recursiva toda la categoría ellas agrupación en su categoría principal.

<?php
  function arboldeCategorias($parent = 0, $spacing = '', $user_tree_array = '') 
  {
    include 'conexion.php';
    if (!is_array($user_tree_array))
    $user_tree_array = array();

    $sql = "SELECT `id_categoria`, `nombre`, `id_padre` FROM `categorias` WHERE 1 AND `id_padre` = $parent ORDER BY id_categoria ASC";
    $query = $connection->prepare($sql);
    $query->execute();
    $total = $query->rowCount();

    if ($total > 0) 
    {
      while ($row = $query->fetch(PDO::FETCH_OBJ)) 
      {
        $user_tree_array[] = array("id" => $row->id_categoria, "name" => $spacing . $row->nombre);
        $user_tree_array = arboldeCategorias($row->id_categoria, $spacing . '&nbsp;&nbsp;', $user_tree_array);
      }
    }
    return $user_tree_array;
  }
  ?>

El funcionamiento de esta función es bastante simple. Se iniciará su iteración con la categoría padre y llamará a la función propia si tiene la categoría infantil y otra vez si niño tiene del niño hasta que el niño tenga ningún niño.

El valor devuelto por la función se almacena en la matriz y se lleva hacia adelante en la función recursiva. Así que, finalmente, al final de la función tendremos una matriz con todas las categorías agrupadas en las subcategorías.

El parámetro $spacing es simplemente para el espaciado de la categoría infantil.
Mostrar árbol de categorías en una lista desplegable.

  <?php 
    $categoryList = arboldeCategorias();
  ?>

  <select>
    <?php foreach($categoryList as $cl) { ?>
      <option value="<?php echo $cl["id"] ?>"><?php echo $cl["name"]; ?></option>
    <?php } ?>
  </select>

Mostrar árbol de Categoría en formato de lista.

Función:

<?php 
  function arboldeCategoriasLista($parent = 0, $user_tree_array = '') 
  {
    include 'conexion.php';
    if (!is_array($user_tree_array))
    $user_tree_array = array();

    $sql = "SELECT `id_categoria`, `nombre`, `id_padre` FROM `categorias` WHERE 1 AND `id_padre` = $parent ORDER BY id_categoria ASC";
    $query = $connection->prepare($sql);
    $query->execute();
    $total = $query->rowCount();

    if ($total > 0) 
    {
      $user_tree_array[] = "<ul>";
      while ($row = $query->fetch(PDO::FETCH_OBJ)) 
      {
        $user_tree_array[] = "<li>". $row->nombre."</li>";
        $user_tree_array = arboldeCategoriasLista($row->id_categoria, $user_tree_array);
      }
      $user_tree_array[] = "</ul>";
    }
    return $user_tree_array;
  }
?>

Mostrar Lista:

<ul>
<?php
  $res = arboldeCategoriasLista();
  foreach ($res as $r) {
    echo  $r;
  }
?>
</ul>

Fuente de apoyo: http://goo.gl/G5eC76