Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何从递归查询构建嵌套div的精确形式?_Php_Html - Fatal编程技术网

Php 如何从递归查询构建嵌套div的精确形式?

Php 如何从递归查询构建嵌套div的精确形式?,php,html,Php,Html,我有一个有点复杂的递归postgresql查询,它引入了如下内容(为了解决这个问题,我简化了它): id depth path has_children 1 1 1 true 2 2 1.2 true 3 3 1.2.3 true 4 4 1.2.3.4 true 5 5 1.2.3.4.5 false 6 1 6

我有一个有点复杂的递归postgresql查询,它引入了如下内容(为了解决这个问题,我简化了它):

id  depth   path        has_children

1   1       1           true
2   2       1.2         true
3   3       1.2.3       true
4   4       1.2.3.4     true
5   5       1.2.3.4.5   false
6   1       6           true
7   2       6.7         true
8   3       6.7.8       false
9   1       9           false
10  1       10          true
11  2       10.11       false
这是作为获取的结果(对于那些想知道为什么我将一些数组解析为对象的人来说,这是因为行作为对象获取,而我只是复制结果):

我想将结果转换为(使用给定的类名):


一,

1.2

1.2.3

1.2.3.4

1.2.3.4.5

六,

6.7

6.7.8

九,

十,

10.11

然而,在看了太多涉及
ul
li
的例子后,我感到困惑不解。由于嵌套的
ul
s和
li
s与嵌套的
div
s不同,因此调整此类示例以供我使用失败


我想要一个干净的解决方案,使用
foreach
(最好)或
while
循环(不需要递归函数)。我也不希望将结果重新创建为多维数组。

您需要将db数据提取到一个数组中,该数组可以循环使用深度和子数组,并将数据传递到一个新的多维数组,如下所示:

array(
    '1' => array(
        '1.2' => array(
            '1.2.3' => array(
                '1.2.3.4' => array('1.2.3.4.5')
            )
        )
    ),
    '6' => array(
        '6.7' => array('6.7.8')
    )
);
然后,您可以循环它,并使用foreach将每个数组作为div进行回显

假设您以
array('row'=>array('key'=>'value','etc'=>'more'))的形式发布了从示例表中获取的数据。对于每一行,您需要检查
['has_children']
值。如果它的计算结果为true,那么应该将深度作为一个整数,并使用for循环,例如
for($i=0;$i$path){
if(is_数组($path)){
//检查是否是第一个。
$class=(strpos('.',$name))?'baz':'bar';
回显“\n\t”;
echo“\n\t{$name}

\n\n\n”; 显示($path); 回声“; }否则{ 回显“\n\t”; echo“\n\t{$path}

\n”; 回声“; } } }

正在进行中,但我希望您能理解主要思想。

您需要将db数据提取到一个数组中,该数组可以循环使用深度和子元素,并将数据传递到一个新的多维数组,如下所示:

array(
    '1' => array(
        '1.2' => array(
            '1.2.3' => array(
                '1.2.3.4' => array('1.2.3.4.5')
            )
        )
    ),
    '6' => array(
        '6.7' => array('6.7.8')
    )
);
然后,您可以循环它,并使用foreach将每个数组作为div进行回显

假设您以
array('row'=>array('key'=>'value','etc'=>'more'))的形式发布了从示例表中获取的数据。对于每一行,您需要检查
['has_children']
值。如果它的计算结果为true,那么应该将深度作为一个整数,并使用for循环,例如
for($i=0;$i$path){
if(is_数组($path)){
//检查是否是第一个。
$class=(strpos('.',$name))?'baz':'bar';
回显“\n\t”;
echo“\n\t{$name}

\n\n\n”; 显示($path); 回声“; }否则{ 回显“\n\t”; echo“\n\t{$path}

\n”; 回声“; } } }

正在运行中,但我希望您了解主要思想。

您的数据是扁平的,这使得编写递归函数更加困难。递归函数最自然地处理嵌套数据。这花了一段时间,但我能够创建一个部分递归的解决方案来处理平面数据

<?php
$tree = array(array("id"=>1,"depth"=>1,"path"=>"1","has_children"=>true),array("id"=>2,"depth"=>2,"path"=>"1.2","has_children"=>true),array("id"=>3,"depth"=>3,"path"=>"1.2.3","has_children"=>true),array("id"=>4,"depth"=>4,"path"=>"1.2.3.4","has_children"=>true),array("id"=>5,"depth"=>5,"path"=>"1.2.3.4.5","has_children"=>false),array("id"=>6,"depth"=>1,"path"=>"6","has_children"=>true),array("id"=>7,"depth"=>2,"path"=>"6.7","has_children"=>true),array("id"=>8,"depth"=>3,"path"=>"6.7.8","has_children"=>false),array("id"=>9,"depth"=>1,"path"=>"9","has_children"=>false),array("id"=>10,"depth"=>1,"path"=>"10","has_children"=>true),array("id"=>11,"depth"=>2,"path"=>"10.11","has_children"=>false));

header('Content-Type: text/plain');

function print_tree(&$tree, $i, $top_level)
{
    $indent = str_repeat('    ', $tree[$i]['depth']);

    echo $indent."<div class=\"".($top_level ? 'bar' : 'baz')."\">\n";
    echo $indent."    <div class=\"qux\">\n";
    echo $indent."        <p>".$tree[$i]['path']."</p>\n";
    echo $indent."    </div>\n";

    if($tree[$i]['has_children'])
    {
        print_tree($tree, $i+1, false);
    }

    echo $indent."</div>\n";
}

echo "<div id=\"foo\">\n";

$count = count($tree);
for($i = 0; $i < $count; ++$i)
{
    if($tree[$i]['depth'] == 1)
    {
        print_tree($tree, $i, true);
    }
}

echo "</div>\n";
?>

这将输出:

<div id="foo">
    <div class="bar">
        <div class="qux">
            <p>1</p>
        </div>
        <div class="baz">
            <div class="qux">
                <p>1.2</p>
            </div>
            <div class="baz">
                <div class="qux">
                    <p>1.2.3</p>
                </div>
                <div class="baz">
                    <div class="qux">
                        <p>1.2.3.4</p>
                    </div>
                    <div class="baz">
                        <div class="qux">
                            <p>1.2.3.4.5</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="bar">
        <div class="qux">
            <p>6</p>
        </div>
        <div class="baz">
            <div class="qux">
                <p>6.7</p>
            </div>
            <div class="baz">
                <div class="qux">
                    <p>6.7.8</p>
                </div>
            </div>
        </div>
    </div>
    <div class="bar">
        <div class="qux">
            <p>9</p>
        </div>
    </div>
    <div class="bar">
        <div class="qux">
            <p>10</p>
        </div>
        <div class="baz">
            <div class="qux">
                <p>10.11</p>
            </div>
        </div>
    </div>
</div>

一,

1.2

1.2.3

1.2.3.4

1.2.3.4.5

六,

6.7

6.7.8

九,

十,

10.11


您的数据是扁平的,这使得编写递归函数更加困难。递归函数最自然地处理嵌套数据。这花了一段时间,但我能够创建一个部分递归的解决方案来处理平面数据

<?php
$tree = array(array("id"=>1,"depth"=>1,"path"=>"1","has_children"=>true),array("id"=>2,"depth"=>2,"path"=>"1.2","has_children"=>true),array("id"=>3,"depth"=>3,"path"=>"1.2.3","has_children"=>true),array("id"=>4,"depth"=>4,"path"=>"1.2.3.4","has_children"=>true),array("id"=>5,"depth"=>5,"path"=>"1.2.3.4.5","has_children"=>false),array("id"=>6,"depth"=>1,"path"=>"6","has_children"=>true),array("id"=>7,"depth"=>2,"path"=>"6.7","has_children"=>true),array("id"=>8,"depth"=>3,"path"=>"6.7.8","has_children"=>false),array("id"=>9,"depth"=>1,"path"=>"9","has_children"=>false),array("id"=>10,"depth"=>1,"path"=>"10","has_children"=>true),array("id"=>11,"depth"=>2,"path"=>"10.11","has_children"=>false));

header('Content-Type: text/plain');

function print_tree(&$tree, $i, $top_level)
{
    $indent = str_repeat('    ', $tree[$i]['depth']);

    echo $indent."<div class=\"".($top_level ? 'bar' : 'baz')."\">\n";
    echo $indent."    <div class=\"qux\">\n";
    echo $indent."        <p>".$tree[$i]['path']."</p>\n";
    echo $indent."    </div>\n";

    if($tree[$i]['has_children'])
    {
        print_tree($tree, $i+1, false);
    }

    echo $indent."</div>\n";
}

echo "<div id=\"foo\">\n";

$count = count($tree);
for($i = 0; $i < $count; ++$i)
{
    if($tree[$i]['depth'] == 1)
    {
        print_tree($tree, $i, true);
    }
}

echo "</div>\n";
?>

这将输出:

<div id="foo">
    <div class="bar">
        <div class="qux">
            <p>1</p>
        </div>
        <div class="baz">
            <div class="qux">
                <p>1.2</p>
            </div>
            <div class="baz">
                <div class="qux">
                    <p>1.2.3</p>
                </div>
                <div class="baz">
                    <div class="qux">
                        <p>1.2.3.4</p>
                    </div>
                    <div class="baz">
                        <div class="qux">
                            <p>1.2.3.4.5</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="bar">
        <div class="qux">
            <p>6</p>
        </div>
        <div class="baz">
            <div class="qux">
                <p>6.7</p>
            </div>
            <div class="baz">
                <div class="qux">
                    <p>6.7.8</p>
                </div>
            </div>
        </div>
    </div>
    <div class="bar">
        <div class="qux">
            <p>9</p>
        </div>
    </div>
    <div class="bar">
        <div class="qux">
            <p>10</p>
        </div>
        <div class="baz">
            <div class="qux">
                <p>10.11</p>
            </div>
        </div>
    </div>
</div>

一,

1.2

1.2.3

1.2.3.4

1.2.3.4.5

六,

6.7

6.7.8

WITH x AS (
    SELECT *
          ,(lag(depth) OVER (ORDER BY id) +1) - depth AS end_divs
          ,CASE WHEN depth = 1 THEN 'bar' ELSE 'baz' END AS class
          ,E'\n' || repeat('    ', depth) AS i -- newline + indent
    FROM   tbl
    ORDER  BY id
    )
SELECT '<div id="foo">'
    || string_agg(
          CASE WHEN end_divs > 0 THEN 
             (SELECT string_agg(repeat ('    ', n), E'</div>\n')
              FROM   generate_series (end_divs,0,-1) n)
          ELSE '' END
          || i || '<div class="' || class ||'">'
          || i || '    <div class="qux">'
          || i || '        <p>' || path || '</p>'
          || i || '    </div>'
        , E'\n' ORDER BY id
       )
    || (SELECT E'\n' || string_agg(repeat ('    ', n-1), E'</div>\n')
        FROM   generate_series((SELECT depth+1 FROM tbl ORDER BY id DESC LIMIT 1)
                              , 0 , -1) n)
FROM   x;
<div id="foo">
<?php

$openingElement = true;
$divsOpened = 0;
$indent = 1;

foreach ($tree as $row) {
    if ($openingElement === true) {
        print str_repeat(' ', $indent * 4) . '<div class="bar">' . PHP_EOL;
    } else {
        print str_repeat(' ', $indent * 4) . '<div class="baz">' . PHP_EOL;
    }

    $indent++;
    $divsOpened++;

    print str_repeat(' ', $indent * 4) . '<div class="qux">' . PHP_EOL;
    $indent++;
    print str_repeat(' ', $indent * 4) . '<p>' . $row->path . '</p>' . PHP_EOL;
    $indent--;
    print str_repeat(' ', $indent * 4) . '</div>' . PHP_EOL;

    if ($row->has_children) {
        $openingElement = false;
        print PHP_EOL;
    } else {
        for ($i = $divsOpened; $i > 0; $i--) {
            print str_repeat(' ', $i * 4) . '</div>' . PHP_EOL;
            $indent--;
            $divsOpened--;
        }
        $openingElement = true;
    }
}

?>
</div>