如何从php数组生成菜单列表

时间:2014-05-19 19:01:14

标签: php

我有一个php数组如下:

array(4) {
  ["category_id"]=>
  string(3) "151"
  ["name"]=>
  string(6) "Beauty"
  ["href"]=>
  string(70) "http://mydomain.com/thestar/index.php?route=product/category&path=151"
  ["menu_level"]=>
  int(1)
}


array(4) {
  ["category_id"]=>
  string(3) "160"
  ["name"]=>
  string(37) "   -Beauty Accessories"
  ["href"]=>
  string(74) "http://mydomain.com/thestar/index.php?route=product/category&path=151_160"
  ["menu_level"]=>
  int(2)
}

array(4) {
  ["category_id"]=>
  string(3) "154"
  ["name"]=>
  string(28) "   -Body Care"
  ["href"]=>
  string(74) "http://mydomain.com/thestar/index.php?route=product/category&path=151_154"
  ["menu_level"]=>
  int(2)
}


array(4) {
  ["category_id"]=>
  string(3) "155"
  ["name"]=>
  string(29) "   -Fragrances"
  ["href"]=>
  string(74) "http://mydomain.com/thestar/index.php?route=product/category&path=151_155"
  ["menu_level"]=>
  int(2)
}

array(4) {
  ["category_id"]=>
  string(3) "156"
  ["name"]=>
  string(44) "      -For Her"
  ["href"]=>
  string(78) "http://mydomain.com/thestar/index.php?route=product/category&path=151_155_156"
  ["menu_level"]=>
  int(3)
}

array(4) {
  ["category_id"]=>
  string(3) "157"
  ["name"]=>
  string(44) "      -For Him"
  ["href"]=>
  string(78) "http://mydomain.com/thestar/index.php?route=product/category&path=151_155_157"
  ["menu_level"]=>
  int(3)
}

array(4) {
  ["category_id"]=>
  string(3) "153"
  ["name"]=>
  string(28) "   -Hair Care"
  ["href"]=>
  string(74) "http://mydomain.com/thestar/index.php?route=product/category&path=151_153"
  ["menu_level"]=>
  int(2)
}

如何根据每个数组元素的menu_level值生成多级菜单。 我需要一个<ul><li>菜单结构。

我想生产这样的东西:

<ul>
    <li><a>First Level</a>
        <ul>
            <li><a>Second Level</a></li>
            <li><a>Second Level</a></li>
            <li><a>Second Level</a></li>
        </ul>
    </li>
    <li><a>First Level</a>
        <ul>
            <li><a>Second Level</a>
                <ul>
                    <li><a>Third Level</a></li>
                    <li><a>Third Level</a></li>
                    <li><a>Third Level</a>
                        <ul>
                            <li><a>Fourth Level</a></li>
                            <li><a>Fourth Level</a></li>
                            <li><a>Fourth Level</a>
                                <ul>
                                    <li><a>Fifth Level</a></li>
                                    <li><a>Fifth Level</a></li>
                                    <li><a>Fifth Level</a></li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li><a>Second Level</a></li>
        </ul>
    </li>
    <li><a>First Level</a>
        <ul>
            <li><a>Second Level</a></li>
            <li><a>Second Level</a></li>
        </ul>
    </li>

1 个答案:

答案 0 :(得分:0)

这里的主要想法是递归。在您的数据中,它目前是持平的。您需要首先正确构建阵列并确定其中的孩子是谁。例如:内部香水,男士和女士,所以这意味着他们是孩子。首先必须是这样。

在完成数组结构之后,你需要一个递归函数来遍历那个数组,然后从那里构建列表。考虑这个例子:

// dummy data (original flat array)
$raw_data = array(
    array(
        'category_id' => '151',
        'name' => 'Beauty',
        'href' => 'http://mydomain.com/thestar/index.php?route=product/category&path=151',
        'menu_level' => 1,
    ),
    array(
        'category_id' => '160',
        'name' => 'Beauty Accessories',
        'href' => 'http://mydomain.com/thestar/index.php?route=product/category&path=151_160',
        'menu_level' => 2,
    ),
    array(
        'category_id' => '154',
        'name' => 'Body Care',
        'href' => 'http://mydomain.com/thestar/index.php?route=product/category&path=151_154',
        'menu_level' => 2,
    ),
    array(
        'category_id' => '155',
        'name' => 'Fragrances',
        'href' => 'http://mydomain.com/thestar/index.php?route=product/category&path=151_155',
        'menu_level' => 2,
    ),
    array(
        'category_id' => '156',
        'name' => 'For Her',
        'href' => 'http://mydomain.com/thestar/index.php?route=product/category&path=151_155_156',
        'menu_level' => 3,
    ),
    array(
        'category_id' => '157',
        'name' => 'For Him',
        'href' => 'http://mydomain.com/thestar/index.php?route=product/category&path=151_155_157',
        'menu_level' => 3,
    ),
    array(
        'category_id' => '153',
        'name' => 'Hair Care',
        'href' => 'http://mydomain.com/thestar/index.php?route=product/category&path=151_153',
        'menu_level' => 2,
    ),
    array(
        'category_id' => '152',
        'name' => 'Cloth Care',
        'href' => 'http://mydomain.com/thestar/index.php?route=product/category&path=152',
        'menu_level' => 1,
    ),

);

// this function fixes the structure, putting children on their proper parents
function recurse_structure($data) {
    $formatted_data = array();
    foreach($data as $key => $value) {

        // check if this current iteration is a parent or child, check thru path string
        $id = parse_url($value['href'], PHP_URL_QUERY);
        parse_str($id, $href);
        $id = explode('_', $href['path']);

        // if its nested create a indexed path
        if(count($id) > 1) {
            $index = '['.implode('][', $id).']'; // create an array assignment
            $evaluate_string = '$formatted_data' . $index.' = $value;'; // build eval string
            eval($evaluate_string);
        } else {
            // just a normal parent
            $formatted_data[$value['category_id']] = $value;
        }

    }

    return $formatted_data;
}

$formatted_data = recurse_structure($raw_data); // feed the raw data into the formatting

// this method make the list
function build_list($data) {
    $list = (is_array($data)) ? "<ul>" : "";
    foreach($data as $attr => $item) {
        if(is_array($item) || is_object($item)) {
            $list .= build_list($item);
        } else {
            if($attr == "name") {
                $list .= "<li><a href=$data[href]>$item</a></li>";
            }
        }
    }

    $list .= (is_array($data)) ? "</ul>" : "";

    return $list;
}

$list = build_list($formatted_data); // feed the build_list function with formatted

print_r($list); // final output