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


how to generate menu list from php arrray

我有一个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>

这里的主要思想是递归。在你的数据中,它目前是平坦的。首先,您需要正确地构建数组并确定它是谁的子数组。例如:在香水里,男人和女人都有,所以这意味着他们是孩子。必须先那样做。

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

// 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