繁体   English   中英

创建递归类别树函数

[英]Creating a recursive category tree function

我有一个包含许多类别的数据库,有些是儿童:

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => Home Improvement
            [slug] => Home-Improvement
            [parent] => 
            [user_id] => 1
            [order] => 1
        )

    [1] => Array
        (
            [id] => 2
            [name] => Asbestos Abatement & Removal
            [slug] => Asbestos-Abatement-Removal
            [parent] => 1
            [user_id] => 1
            [order] => 8
        )

    [2] => Array
        (
            [id] => 3
            [name] => Asphalt & Asphalt Products
            [slug] => Asphalt-Asphalt-Products
            [parent] => 1
            [user_id] => 1
            [order] => 9
        )

    [3] => Array
        (
            [id] => 4
            [name] => Bathroom
            [slug] => Bathroom
            [parent] => 1
            [user_id] => 1
            [order] => 10
        )

    [4] => Array
        (
            [id] => 5
            [name] => Kitchen Cabinets
            [slug] => Kitchen-Cabinets
            [parent] => 1
            [user_id] => 1
            [order] => 11
        )

    [5] => Array
        (
            [id] => 6
            [name] => Ceilings
            [slug] => Ceilings
            [parent] => 1
            [user_id] => 1
            [order] => 12
        )

    [6] => Array
        (
            [id] => 7
            [name] => Cleaning
            [slug] => Cleaning
            [parent] => 1
            [user_id] => 1
            [order] => 13
        )

    [7] => Array
        (
            [id] => 8
            [name] => Closet Organizers & Accessories
            [slug] => Closet-Organizers-Accessories
            [parent] => 1
            [user_id] => 1
            [order] => 14
        )

    [8] => Array
        (
            [id] => 9
            [name] => Concrete
            [slug] => Concrete
            [parent] => 1
            [user_id] => 1
            [order] => 15
        )

    [9] => Array
        (
            [id] => 10
            [name] => Contractors & Service Providers
            [slug] => Contractors-Service-Providers
            [parent] => 1
            [user_id] => 1
            [order] => 16
        )

我想要输出的是这样的:

<ul>
    <li>Parent
        <ul>
            <li>Child</li>
        </ul>
    </li>
    <li>Parent with no Children</li>
</ul>

我正在尝试用PHP构建一个递归树脚本,但是我被卡住了。 这是我到目前为止所拥有的。 我坚持要在别人之间做什么:和endif; 在foreach。 (我正在使用这种语法只是为了更容易阅读。)有什么建议吗?

echo $this->categories->makeTree(0, $this->db->get('categories')->result_array());

public static function makeTree($parent, $array)
{
  if (!is_array($array)) return '';

  $output = '<ul>';

  foreach($array as $key => $value):
    if ($value['parent'] == $parent):
        $output .= '<li>';

        if ($value['parent'] == NULL):
            $output .= $value['name'];
        else:

        endif;
    endif;

    $output .= '</li>';
  endforeach;

  $output .= '</ul>';
  return $output;
}

编辑1

我能够使这个工作,虽然我在foreach循环中有一个数据库调用,这可能不是最好的主意:

public function makeTree($parent, $array)
{
  if (!is_array($array)) return FALSE;

  $output = '<ul>';

  foreach($array as $key => $value):
    if ($value['parent'] == $parent):
        $output .= '<li>';

        if ($value['parent'] == NULL):
            $output .= $value['name'];

            $subcategories = ci()->db->get_where('categories', array('parent' => $value['id']));

            if ($subcategories->num_rows() > 0):
                $output .= $this->makeTree($value['id'], $subcategories->result_array());
            endif;
        else:
            $output .= $value['name'];
            $output .= '</li>';
        endif;
    endif;

  endforeach;

  $output .= '</ul>';
  return $output;
}

编辑2

这是我的最终解决方案,重用数组而不是进行数据库查询:

public function makeTree($parent, $array)
{
  if (!is_array($array) OR empty($array)) return FALSE;

  $output = '<ul>';

  foreach($array as $key => $value):
    if ($value['parent'] == $parent):
        $output .= '<li>';

        if ($value['parent'] == NULL):
            $output .= $value['name'];

            $matches = array();

            foreach($array as $subkey => $subvalue):
                if ($subvalue['parent'] == $value['id']):
                    $matches[$subkey] = $subvalue;
                endif;
            endforeach;

            $output .= $this->makeTree($value['id'], $matches);

        else:
            $output .= $value['name'];
            $output .= '</li>';
        endif;
    endif;

  endforeach;

  $output .= '</ul>';

  return $output;
}

虽然这似乎得到了回答,但请看这里 使用显示的功能,您只需一次迭代即可将平面数据转换为嵌套数据。 从那个嵌套数据创建ul-list非常容易。 例如:

function nested2ul($data) {
  $result = array();

  if (sizeof($data) > 0) {
    $result[] = '<ul>';
    foreach ($data as $entry) {
      $result[] = sprintf(
        '<li>%s %s</li>',
        $entry['name'],
        nested2ul($entry['children'])
      );
    }
    $result[] = '</ul>';
  }

  return implode($result);
}

echo nested2ul(array(flat2nested( $yourFlatData ));

这种方法的好处在于您不必为了找到子元素而一次又一次地对输入数据进行重复迭代。

这是我的最终解决方案,重用数组而不是进行数据库查询。 如果您有更好的解决方案,请发布!

public function makeTree($parent, $array)
{
  if (!is_array($array) OR empty($array)) return FALSE;

  $output = '<ul>';

  foreach($array as $key => $value):
    if ($value['parent'] == $parent):
        $output .= '<li>';

        if ($value['parent'] == NULL):
            $output .= $value['name'];

            $matches = array();

            foreach($array as $subkey => $subvalue):
                if ($subvalue['parent'] == $value['id']):
                    $matches[$subkey] = $subvalue;
                endif;
            endforeach;

            $output .= $this->makeTree($value['id'], $matches);

        else:
            $output .= $value['name'];
            $output .= '</li>';
        endif;
    endif;

  endforeach;

  $output .= '</ul>';

  return $output;
}

我通常会使用这样的东西,请注意

第一段这段代码使用了弃用的mysql_ *

第二个你应该有一个名为level的数据库字段,如果是NULL它是主要类别,如果它有一个数字,它是该类别的子类别,该数字为id

function getFamilies($level = 0) {
    $level++;
    $sql = "SELECT id from families WHERE level IS NULL";
    if (mysql_num_rows($result) > 0) {
        echo "<ul>";
            while($row = mysql_fetch_assoc($result)) {
                echo "<li>".$row['id'];
                    getSubFamilies($level, $row['id']);
                echo "</li>";
            }
        echo "</ul>";
    }
}

function getSubFamilies($level, $id) {
    $level++;
    $sqlSubFamilies = "SELECT id  FROM families WHERE level = ".$id."";
    $resultSubFamilies = mysql_query($sqlSubFamilies);
    if (mysql_num_rows($resultSubFamilies) > 0) {
        echo = "<ul>";
            while($rowSubFamilies = mysql_fetch_assoc($resultSubFamilies)) {
                echo "<li>".$rowSubFamilies['id'];
                    getSubFamilies($level, $rowSubFamilies['id']);
                echo "</li>";
            }
        echo "</ul>";
    }
}

getFamilies($level = 0);

尝试这个:

$cats = $this->db->get('categories')->result_array();

echo $this->categories->makeTree(0, $cats);

public static function makeTree($parent, $array)
{
  if (!is_array($array)) return '';

  $output = '<ul>';

  foreach($array as $key => $value):
    if ($value['parent'] == $parent):
        $output .= '<li>';

        if ($value['parent'] == NULL):
            $output .= $value['name'];
        else:

        endif;
    endif;

    $output .= '</li>';

    $output .= $this->categories->makeTree($value['parent'], $cats);

  endforeach;

  $output .= '</ul>';
  return $output;
}

我认为这种使用匿名函数的方法非常简单。

//--------------------------- PRINT NESTED CATEGORIES
$cats_childs = array();

$q = $db->query("SELECT id, parent, name FROM categories");

while ($r = $db->row($q))
{
    $cats_childs[$r['parent']][$r['id']] = $r;
}

$nested2ul = function($data) use (&$nested2ul, &$cats_childs) {
    if (!empty($data)) {
        echo '<ul>';
        foreach ($data as $r) {
            echo '<li>';
            echo $r['name'];
            $flat2ul($cats_childs[$r['id']]);
            echo '</li>';
        }
        echo '</ul>';
    }
};

echo $nested2ul($cats_childs[0]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM