Yanick Lafontaine
Yanick Lafontaine

Reputation: 190

Generate HTML from multidimensional array

I would like to generate HTML code like this with php:

<li id="821">Accessoires tablette et cellulaire
  <ul>
    <li id="426">Accessoires pour cellulaire
      <ul>
        <li id="675">Supports et stations d'accueil</li>
        <li id="680">Chargeurs maison et automobile
          <ul>
            <li id="689">Chargeurs pour cellulaire</li>
            <li id="690">Chargeurs pour téléphone intelligent</li>
          </ul>
        </li>
        <li id="681" >Pellicules protectrices</li>
        <li id="682" >Câbles et adaptateurs pour cellulaire</li>
        <li id="683" >Autres accessoires</li>
        <li id="684" >Lentilles pour iPhone</li>
        <li id="687" >Étuis pour cellulaire</li>
        <li id="688" >Accessoires Bluetooth et mains libres</li>
      </ul>
    <li id="132">Accessoires - iPod et lecteur MP3
      <ul>
        <li id="238" >Émetteurs FM</li>
        <li id="254" >Étuis protecteurs et sacs de transport</li>
        <li id="272" >Accessoires</li>
        <li id="356" >Lecteurs MP3</li>
      </ul>
    </li>
    <li id="347">Accessoires pour tablette
      <ul>
        <li id="481" >Stylos et clavier</li>
        <li id="482" >Câbles et adaptateurs</li>
        <li id="486" >Chargeurs maison et automobile</li>
        <li id="489" >Étuis protecteurs et sacs de transport</li>
        <li id="485" >Supports et stations d'accueil</li>
      </ul>
    </li>
  </ul>
</li>

From the array that I show in example. The array looks like this: Array example

The <li> HTML id need to be the category_id from the array and the <li> text need to be the name from the array.

I need to use all children from the array to.

For now I have something like this:

    function generate_tree($item, $key)
{
    if ($key == "category_id"){
        echo "<li id=\"$item\">";
    }

    if ($key == "name"){
        echo "$item</li>\n";
    }
}

array_walk_recursive($cat, 'generate_tree');

But this sample code put all items on same level like this:

<li id="18">Produits</li>
<li id="821">Accessoires tablette et cellulaire</li>
<li id="426">Accessoires pour cellulaire</li>
<li id="675">Supports et stations d'accueil</li>
<li id="680">Chargeurs maison et automobile</li>
<li id="689">Chargeurs pour cellulaire</li>
<li id="690">Chargeurs pour téléphone intelligent</li>
<li id="681">Pellicules protectrices</li>
<li id="682">Câbles et adaptateurs pour cellulaire</li>
<li id="683">Autres accessoires</li>
<li id="684">Lentilles pour iPhone</li>
<li id="687">Étuis pour cellulaire</li>
<li id="688">Accessoires Bluetooth et mains libres</li>
<li id="132">Accessoires - iPod et lecteur MP3</li>
<li id="238">Émetteurs FM</li>
<li id="254">Étuis protecteurs et sacs de transport</li>
<li id="272">Accessoires</li>
<li id="356">Lecteurs MP3</li>
<li id="347">Accessoires pour tablette</li>
<li id="481">Stylos et clavier</li>
<li id="482">Câbles et adaptateurs</li>
<li id="486">Chargeurs maison et automobile</li>
<li id="489">Étuis protecteurs et sacs de transport</li>
<li id="485">Supports et stations d'accueil</li>
<li id="136">Alarmes et sécurité</li>
<li id="825">Domotique</li>
<li id="828">Capteur de température</li>
<li id="618">Carillon de porte et accessoires</li>
<li id="826">Contrôle d'électroménager et de luminaire</li>

How can I generate multiple level with <ul>?

Upvotes: 1

Views: 60

Answers (2)

dcromley
dcromley

Reputation: 1410

Here is an recursive example adapted to your data:

<?php
$var1 = array(
'0' => array(
  'one' => '426', 'two' => 'alpha', 'three' => array(
    '0' => array(
      'one' => '675', 'two' => 'beta', 'three' => array() ),
    '1' => array(
      'one' => '680', 'two' => 'gamma', 'three' => array(
        '0' => array(
          'one' => '689', 'two' => 'delta', 'three' => array() ),
        '1' => array(
          'one' => '690', 'two' => 'epsilon', 'three' => array() ), ) ),
    '2' => array(
      'one' => '681', 'two' => 'zeta', 'three' => array() ),
    '3' => array(
      'one' => '682', 'two' => 'eta', 'three' => array() ) ) ) );

  doit($var1, '');

function doit($a1, $indent) {
  if (count($a1) == 0) return;
  echo "$indent<ul>\n";
  foreach ($a1 as $a2) {
    $v1 = $a2['one'];
    $v2 = $a2['two'];
    echo "  $indent<li id=\"$v1\">$v2</li>\n";
    doit($a2['three'], "    $indent"); }
  echo "$indent</ul>\n";
  }
?>

EDIT: To make it pass HTML validation:
(Proper way to make HTML nested list?)

function doit($a1, $indent) {
  if (count($a1) == 0) return;
  echo "\n$indent<ul>\n";
  foreach ($a1 as $a2) {
    $v1 = $a2['one'];
    $v2 = $a2['two'];
    echo "$indent<li id=\"$v1\">$v2";
    doit($a2['three'], "    $indent");
    echo "</li>\n"; }
  echo "$indent</ul>";
  }

Upvotes: 1

Xeschylus
Xeschylus

Reputation: 148

For your situation, it seems a recursive function would be best. The following might do:

function recursion($level, $data)
{
   if($level < 10)
   {
      foreach($data as $key => $value) 
      {
       //echo <li>

      if(!empty($value['children']))
      {
         //echo <ul> here
         recursion($level+1. $value)
         //echo </ul> here
      }
      //echo </li> here
      }


   }
}

This prevents writing repetitive code and is a fairly common practice. I also added a variable $level with a check to prevent going too deep which I always add as a way to reduce the probability of infinite recursion.

Hope that helps.

Upvotes: 2

Related Questions