Learning and sharing
Learning and sharing

Reputation: 1388

Sort an array with PHP to generate a multilevel menu listing

I am trying to generate a list of multilevel menu in PHP but I have not got how to do it, I would like to help me with simple examples and sort Categories and Sub categories with their title, something like this:

<ul>
  <li>Category 1</li>
  <li>
    <h4>TITLE HERE</h4>
    <ul>
      <li>Category Child 1</li>
      <li>Category Child 2</li>
      <li>Category Child 3</li>
      <li>
        <h4>TITLE HERE</h4>
        <ul>
          <li>Category child 1</li>
          <li>Category child 2</li>
          <li>Category child 3</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Category 1</li>
  <li>Category 2</li>
  <li>Category 3</li>
</ul>

I have an array in PHP:

$data = Array (
  '0' => Array (
      'id' => '1',
      'id_parent' => '',
      'name' => 'Sports'
  ),

  '1' => Array (
      'id' => '2',
      'id_parent' => '1',
      'name' => 'Football'
  ),

  '2' => Array (
      'id' => '3',
      'id_parent' => '1',
      'name' => 'Bascket'
  ),

  '3' => Array (
      'id' => '4',
      'id_parent' => '',
      'name' => 'Health'
  ),

  '4' => Array (
      'id' => '5', 
      'id_parent' => '4',
      'name' => 'Nutrition and diet'
  ),

  '5' => Array (
      'id' => '6',
      'id_parent' => '4',
      'name' => 'Beauty Salon'
  ),

  '6' => Array (
      'id' => '7',
      'id_parent' => '',
      'name' => 'Films'
  ),

  '7' => Array (
      'id' => '8',
      'id_parent' => '7',
      'name' => 'Armageddon'
  ),

  '8' => Array (
      'id' => '9',
      'id_parent' => '7',
      'name' => 'Apocalypse'
  ),

  '9' => Array (
      'id' => '10',
      'id_parent' => '',
      'name' => 'News'
  ),

  '10' => Array (
      'id' => '11',
      'id_parent' => '10',
      'name' => 'International'
  ),

  '11' => Array (
      'id' => '12',
      'id_parent' => '11',
      'name' => 'News from Syria'
  ),

  '12' => Array (
      'id' => '13',
      'id_parent' => '11',
      'name' => 'News from Palestine'
  )
);

I have a table in MySQL:

CREATE TABLE `categories` (
  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `id_parent` mediumint(8) unsigned DEFAULT NULL,
  `name` varchar(100) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `FK_categories_UNIQUE` (`name`),
  KEY `FK_categories` (`id_parent`),
  CONSTRAINT `FK_categories` FOREIGN KEY (`id_parent`) REFERENCES `categories` (`id`) ON UPDATE CASCADE
)   ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of categories
-- ----------------------------

INSERT INTO `categories` VALUES ('1', null, 'Sports');
INSERT INTO `categories` VALUES ('2', '1', 'Football');
INSERT INTO `categories` VALUES ('3', '1', 'Bascket');
INSERT INTO `categories` VALUES ('4', null, 'Health');
INSERT INTO `categories` VALUES ('5', '4', 'Nutrition and diet');
INSERT INTO `categories` VALUES ('6', '4', 'Beauty Salon');
INSERT INTO `categories` VALUES ('7', null, 'Films');
INSERT INTO `categories` VALUES ('8', '7', 'Armageddon');
INSERT INTO `categories` VALUES ('9', '7', 'Apocalypse');
INSERT INTO `categories` VALUES ('10', null, 'News');
INSERT INTO `categories` VALUES ('11', '10', 'International');
INSERT INTO `categories` VALUES ('12', '11', 'News from Syria');
INSERT INTO `categories` VALUES ('13', '11', 'News from Palestine');

Upvotes: 1

Views: 311

Answers (1)

Anar Bayramov
Anar Bayramov

Reputation: 11584

I am going to help you, but I would love to to say couple of things first;

Your database design is not proper. if you are giving parent_id for each element you should have given parent_id 0 or in best case null for top parent too. That way we could reduce first foreach and just fetch main categories automatically.

Maybe now you have very a few values but in future you should consider this. Think about that if you had thousands of news, categories and each time you have to loop through all the data.

Anyway here is your code

$parents = array();

foreach ($data as $key => $item) {
    if($item['id_parent'] === '') {
        $parents[$key] = $item;
    } 
}

?>

<ul>

<?php foreach ($parents as $parent) { ?>
     <li> <?php $parent['name'] ?> </li>
     <ul>
   <?php foreach ($data as $key => $item)  { ?>
        <?php if ($parent['id'] == $item['id_parent'])  { ?>
        <li> <?php $item['name'] ?> </li> 
        <?php } ?>
    <?php } ?>
    </ul> 
<?php } ?>

and this is the result

enter image description here

Upvotes: 1

Related Questions