【问题标题】:Create nested list from PHP array for dropdown select field从 PHP 数组为下拉选择字段创建嵌套列表
【发布时间】:2013-01-14 19:58:12
【问题描述】:

我正在为一个想要变成嵌套的数组而苦苦挣扎

我需要:

<select>
<option value="1">Top1</option>
<option value="2">Top2</option>
<option value="9">Top3</option>
<option value="7"> - - Top3.1</option>
<option value="5"> - - Top3.2</option>
<option value="12">- - - - Top3.2.1</option>
<option value="6">Top4</option>
<option value="4">Top5</option>
<option value="8"> - - Top5.1</option>
<option value="3"> - - Top5.2</option>

我不能使用 optgroup,因为一切都是可选的。据我所知,您无法选择 optgroup 标签。

我的数组如下所示:

[44] => Array
    (
        [id] => 1
        [name] => Test
        [slug] => test
        [parent] => 0
    )

[45] => Array
    (
        [id] => 2
        [name] => Test-Sub
        [slug] => test-sub
        [parent] => 1
    )

[46] => Array
    (
        [id] => 3
        [name] => Test-Sub-Sub
        [slug] => test-sub-sub
        [parent] => 2
    )

我感觉我已经尝试了几十种变体,但我无法正确构建我的表单选择。

这是我最后一次尝试:

function toDropdown($arr)
    {
        foreach ($arr as $row) {
            $cat[$row['id']] = $row['name'];
            if ($row['parent'] != 0) {
                $cat[$row['id']] = '--' . $row['name'];
            }
        }
        return $cat;
    }

但是这样一来,按照ID排序,嵌套就失去意义了。

我会继续努力,但如果有人可以提供帮助,我将不胜感激!


编辑:PHP 数据


我从数据库中获取所有类别的功能:

function get_categories($parent = 'all')
{
    $this->db->select('categories.id, categories.name, categories.slug, categories.parent');
    $this->db->from('categories');

    if ($query = $this->db->get())
    {
        return $query->result_array();
    }

    return FALSE;
}

我的view.php,我输出所有数据的地方:

$query = $this->datei_model->get_categories('all');

foreach ($query as $row)
{
    $parents[] = $row;
}

$tree = buildTree($parents);

print("<select>\n");
printTree($tree);
print("</select>");

【问题讨论】:

    标签: php arrays nested hierarchy


    【解决方案1】:

    试试这个;

    function buildTree(Array $data, $parent = 0) {
        $tree = array();
        foreach ($data as $d) {
            if ($d['parent'] == $parent) {
                $children = buildTree($data, $d['id']);
                // set a trivial key
                if (!empty($children)) {
                    $d['_children'] = $children;
                }
                $tree[] = $d;
            }
        }
        return $tree;
    }
    
    
    $rows = array(
        array ('id' => 1, 'name' => 'Test 1', 'parent' => 0),
        array ('id' => 2, 'name' => 'Test 1.1', 'parent' => 1),
        array ('id' => 3, 'name' => 'Test 1.2', 'parent' => 1),
        array ('id' => 4, 'name' => 'Test 1.2.1', 'parent' => 3),
        array ('id' => 5, 'name' => 'Test 1.2.2', 'parent' => 3),
        array ('id' => 6, 'name' => 'Test 1.2.2.1', 'parent' => 5),
        array ('id' => 7, 'name' => 'Test 2', 'parent' => 0),
        array ('id' => 8, 'name' => 'Test 2.1', 'parent' => 7),
    );
    
    $tree = buildTree($rows);
    // print_r($tree);
    
    function printTree($tree, $r = 0, $p = null) {
        foreach ($tree as $i => $t) {
            $dash = ($t['parent'] == 0) ? '' : str_repeat('-', $r) .' ';
            printf("\t<option value='%d'>%s%s</option>\n", $t['id'], $dash, $t['name']);
            if ($t['parent'] == $p) {
                // reset $r
                $r = 0;
            }
            if (isset($t['_children'])) {
                printTree($t['_children'], ++$r, $t['parent']);
            }
        }
    }
    
    
    print("<select>\n");
    printTree($tree);
    print("</select>");
    

    输出;

    <select>
        <option value='1'>Test 1</option>
        <option value='2'>- Test 1.1</option>
        <option value='3'>- Test 1.2</option>
        <option value='4'>-- Test 1.2.1</option>
        <option value='5'>-- Test 1.2.2</option>
        <option value='6'>--- Test 1.2.2.1</option>
        <option value='7'>Test 2</option>
        <option value='8'>- Test 2.1</option>
    </select>
    

    在你的情况下;

    <select>
        <option value='1'>Baden-Württemberg</option>
        <option value='2'>- DMP-Verträge</option>
        <option value='50'>- Sprechstundenbedarf</option>
        <option value='52'>- Richtgrößen</option>
        <option value='53'>- Prüfungen</option>
        <option value='54'>- DMP-Verträge</option>
        <option value='55'>- Sonstige Verträge</option>
        <option value='3'>Berlin</option>
        <option value='62'>- DMP-Verträge</option>
        <option value='63'>- Prüfungen</option>
        <option value='64'>- Richtgrößen</option>
        <option value='65'>- Sonstige Verträge</option>
        <option value='66'>- Sprechstundenbedarf</option>
        <option value='4'>Brandenburg</option>
        <option value='67'>- DMP-Verträge</option>
        <option value='68'>- Prüfungen</option>
        <option value='69'>- Richtgrößen</option>
        <option value='70'>- Sonstige Verträge</option>
        <option value='71'>- Sprechstundenbedarf</option>
        <option value='5'>Bremen</option>
        <option value='72'>- DMP-Verträge</option>
        <option value='73'>- Prüfungen</option>
        <option value='74'>- Richtgrößen</option>
        <option value='75'>- Sonstige Verträge</option>
        <option value='76'>- Sprechstundenbedarf</option>
        <option value='7'>Hessen</option>
        <option value='6'>Hamburg</option>
        <option value='8'>Mecklenburg-Vorpommern</option>
        <option value='9'>Niedersachsen</option>
        <option value='10'>Nordrhein</option>
        <option value='11'>Rheinland-Pfalz</option>
        <option value='12'>Saarland</option>
        <option value='13'>Sachsen</option>
        <option value='14'>Sachsen-Anhalt</option>
        <option value='15'>Schleswig-Holstein</option>
        <option value='16'>Thüringen</option>
        <option value='17'>Westfalen-Lippe</option>
        <option value='51'>Richtgrössen</option>
        <option value='56'>Bayern</option>
        <option value='57'>- DMP-Verträge</option>
        <option value='58'>- Prüfungen</option>
        <option value='59'>- Richtgrößen</option>
        <option value='60'>- Sonstige Verträge</option>
        <option value='61'>- Sprechstundenbedarf</option>
    </select>
    

    【讨论】:

    • 哇,谢谢!!该代码很好地打印了我的选择列表。但随着每一个层次的深入,就会有更多的冲刺。 (…) (抱歉,这里无法格式化代码)
    • 是的,你是对的。但是,例如,最后一个子级别不是一个破折号,而是 7 个破折号,虽然它只是在第二个级别。 project-point.de/sub-levels.png
    • 它与您的$rows 结构有关,请参阅$rows 的答案并检查差异,或者也显示您的$rows(但真实的行数据,而不是 print_r'ed)。
    • 我认为两者的结构相同,不是吗?数组 ( [0] => 数组 ( [id] => 1 [name] => 巴登-符腾堡 [slug] => 巴登-符腾堡 [parent] => 0 ) [40] => 数组 ( [id] => 73 [名称] => 普吕芬根 [蛞蝓] => 普吕芬根 [父] => 5 ) )
    • 兄弟,只是显示所有数据,如上一张图片吗?通过单击编辑按钮将其添加到您的问题中,但真正的 PHP 数据,而不是 PRINT_R 输出 PLS!反了?
    【解决方案2】:

    这只是the original code that answered by Qeremy 的一点点变化

    function printTree($tree, $r = 0, $p = null) {
        foreach ($tree as $i => $t) {
            $dash = ($t['parent'] == 0) ? '' : str_repeat('-', $r) .' ';
            printf("\t<option value='%d'>%s%s</option>\n", $t['id'], $dash, $t['name']);
            if (isset($t['_children'])) {
                printTree($t['_children'], $r+1, $t['parent']); 
            }
        }
    }
    

    现在,虚线名称效果很好。 *对不起我的英语

    【讨论】:

      【解决方案3】:

      在 Qeremy 的代码中,只需更改这一行,代码不会给你任何递增的破折号

      $t['parent'] == $p
      

      到->

      $t['parent'] == 0
      

      【讨论】:

      • 你也可以这样做,函数 printTree($tree, $r = 0, $p = 0)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-24
      • 2021-04-25
      相关资源
      最近更新 更多