PHP和MySQL中的嵌套列表

时间:2022-08-12 15:47:40

I am trying to create a nested unordered list using PHP and MySQL (through CodeIgniter, though I don't think that is relevant).

我试图使用PHP和MySQL创建一个嵌套的无序列表(通过CodeIgniter,虽然我不认为这是相关的)。

I've seen a number of solutions that appear to work for lists that have two levels of nesting, but the solution I need has to have three levels. This is the sort of thing I need:

我已经看到了许多解决方案似乎适用于具有两级嵌套的列表,但我需要的解决方案必须有三个级别。这是我需要的东西:

<ul>
    <li>Top Level, Item 1
        <ul>
            <li>Second Level, Item 1
                <ul>
                    <li>Third Level, Item 1</li>
                    <li>Third Level, Item 2</li>
                    <li>Third Level, Item 3</li>
                </ul>
            <li>Second Level, Item 2
                <ul>
                    <li>Third Level, Item 4</li>
                    <li>Third Level, Item 5</li>
                    <li>Third Level, Item 6</li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

The output from my database is, essentially:

我的数据库的输出基本上是:

TOP LEVEL | SECOND LEVEL | THIRD LEVEL
Item 1 | Item 1 | Item 1
Item 1 | Item 1 | Item 2
Item 1 | Item 1 | Item 3
Item 1 | Item 2 | Item 4
Item 1 | Item 2 | Item 5
Item 1 | Item 2 | Item 6

I've tried going through the output from the database, using variables to register which level I am on etc. but I get into an awful mess with closing off each list.

我已经尝试通过数据库的输出,使用变量来注册我在哪个级别等但是我陷入了关闭每个列表的可怕混乱。

Can anyone suggest a way of doing this?

有谁能建议这样做的方法?

2 个解决方案

#1


0  

query

SELECT a.item, b.item, c.item FROM TOP_LEVEL a JOIN SECOND_LEVEL b ON b.level = a.level JOIN THIRD_LEVEL c ON c.level = b.level ORDER BY a.item, b.item, c.item

code

<?php
$q = "SELECT a.item, b.item, c.item FROM TOP_LEVEL a JOIN SECOND_LEVEL b ON b.level = a.level JOIN THIRD_LEVEL c ON c.level = b.level ORDER BY a.item, b.item, c.item ";
...... your database stuff......
...... resulting array should be two-dimensional `$items` ......
$c = 0;
echo "<ul>\n";
while ($c < count($items)) {
    for ($j = 0; $j < count($items[$c][0]); $j++) {
        echo "<li>$items[$c][0]\n";
        echo "<ul>\n";
        for ($k = 0; $k < count($items[$c][1]); $k++) {
            echo "<li>$items[$c][1]\n";
            echo "<ul>\n";
            for ($i = 0; $i < count($items[$c][2]); $i++) {
                echo "<li>$items[$c][2]<\li>\n";
                $c++;
            }
            echo "</ul>\n";
            echo "</li>\n";
                    $c++;
        }
        echo "</ul>\n";
        echo "</li>\n";
            $c++;
    }
    echo "</ul>\n";
}
?>

#2


0  

Thanks for all the assistance, but I think I've cracked it myself, in quite a different way!

感谢所有的帮助,但我想我已经以完全不同的方式破解了它!

The solution provided by @DevishOne got me thinking, and, using that as a bit of a template, I added in variables to identify whether a new sub-list or sub-sub-list should be opened or closed.

@DevishOne提供的解决方案让我思考,并且,使用它作为一个模板,我添加了变量来识别是应该打开还是关闭新的子列表或子子列表。

I'm not claiming this is foolproof, and neither am I claiming it is particularly efficient, but it does the job for me (so far!)

我并不是说这是万无一失的,我也不认为它特别有效,但它确实适合我(到目前为止!)

My solution:

//Placeholder variables
$current_top = '';
$current_second = '';
$current_third = '';

echo '<ul>';
foreach($array as $row) {
    //If it is a new top level item...
    if ($row['top_level'] != $current_top) {
        //If it isn't the very first top level item...
        if ($current_top != '') {
            //Close off all of the other first, second, and third level branches.
            echo '</ul></li></ul></li>';
        }
        //Echo the top level item, including the start of the sub-list.
        echo '<li>'.$row['top_level'].'<ul>';
        //Set the current top level variable to the current top level item.
        $current_top = $row['top_level'];
        //Set the current second level variable back to null (if it isn't already).
        $current_second = '';
    } 
    //If it is a new second level...
    if ($row['second_level'] != $current_second) {
        //If it isn't the very first second level item...
        if ($current_second != '') {
            //Close off all of the other second and third level branches.
            echo '</ul></li>';
        }
        //Echo the second level item, including the start of the sub-sub-list.
        echo '<li>'.$row['second_level'].'<ul>';
        //Set the current second level variable to the current second level item.
        $current_second = $row['second_level'];
        //Set the current third level variable back to null (if it isn't already).
        $current_third = '';
    } 
    //If it is a new third level...
    if ($row['third_level'] != $current_third) {
        //Echo the third level item, and close it off.
        echo '<li>'.$row['third_level'].'</li>';
        //Set the current third level variable to the current third level item.
        $current_third = $row['third_level'];
    }
}
echo '</ul>';

#1


0  

query

SELECT a.item, b.item, c.item FROM TOP_LEVEL a JOIN SECOND_LEVEL b ON b.level = a.level JOIN THIRD_LEVEL c ON c.level = b.level ORDER BY a.item, b.item, c.item

code

<?php
$q = "SELECT a.item, b.item, c.item FROM TOP_LEVEL a JOIN SECOND_LEVEL b ON b.level = a.level JOIN THIRD_LEVEL c ON c.level = b.level ORDER BY a.item, b.item, c.item ";
...... your database stuff......
...... resulting array should be two-dimensional `$items` ......
$c = 0;
echo "<ul>\n";
while ($c < count($items)) {
    for ($j = 0; $j < count($items[$c][0]); $j++) {
        echo "<li>$items[$c][0]\n";
        echo "<ul>\n";
        for ($k = 0; $k < count($items[$c][1]); $k++) {
            echo "<li>$items[$c][1]\n";
            echo "<ul>\n";
            for ($i = 0; $i < count($items[$c][2]); $i++) {
                echo "<li>$items[$c][2]<\li>\n";
                $c++;
            }
            echo "</ul>\n";
            echo "</li>\n";
                    $c++;
        }
        echo "</ul>\n";
        echo "</li>\n";
            $c++;
    }
    echo "</ul>\n";
}
?>

#2


0  

Thanks for all the assistance, but I think I've cracked it myself, in quite a different way!

感谢所有的帮助,但我想我已经以完全不同的方式破解了它!

The solution provided by @DevishOne got me thinking, and, using that as a bit of a template, I added in variables to identify whether a new sub-list or sub-sub-list should be opened or closed.

@DevishOne提供的解决方案让我思考,并且,使用它作为一个模板,我添加了变量来识别是应该打开还是关闭新的子列表或子子列表。

I'm not claiming this is foolproof, and neither am I claiming it is particularly efficient, but it does the job for me (so far!)

我并不是说这是万无一失的,我也不认为它特别有效,但它确实适合我(到目前为止!)

My solution:

//Placeholder variables
$current_top = '';
$current_second = '';
$current_third = '';

echo '<ul>';
foreach($array as $row) {
    //If it is a new top level item...
    if ($row['top_level'] != $current_top) {
        //If it isn't the very first top level item...
        if ($current_top != '') {
            //Close off all of the other first, second, and third level branches.
            echo '</ul></li></ul></li>';
        }
        //Echo the top level item, including the start of the sub-list.
        echo '<li>'.$row['top_level'].'<ul>';
        //Set the current top level variable to the current top level item.
        $current_top = $row['top_level'];
        //Set the current second level variable back to null (if it isn't already).
        $current_second = '';
    } 
    //If it is a new second level...
    if ($row['second_level'] != $current_second) {
        //If it isn't the very first second level item...
        if ($current_second != '') {
            //Close off all of the other second and third level branches.
            echo '</ul></li>';
        }
        //Echo the second level item, including the start of the sub-sub-list.
        echo '<li>'.$row['second_level'].'<ul>';
        //Set the current second level variable to the current second level item.
        $current_second = $row['second_level'];
        //Set the current third level variable back to null (if it isn't already).
        $current_third = '';
    } 
    //If it is a new third level...
    if ($row['third_level'] != $current_third) {
        //Echo the third level item, and close it off.
        echo '<li>'.$row['third_level'].'</li>';
        //Set the current third level variable to the current third level item.
        $current_third = $row['third_level'];
    }
}
echo '</ul>';