【问题标题】:How to build a tree view with PHP / SQL?如何使用 PHP/SQL 构建树视图?
【发布时间】:2010-09-24 22:14:16
【问题描述】:

最好的方法是:

  1. 使用单个查询从数据库中获取数据
  2. 循环遍历结果构建,例如嵌套的无序列表

我的表有 idnameparent_id 列。


这是我上一个答案的更新,带有一个计数器,为每个 ul 提供一个嵌套“级别”类和一些 cmets。

有人可以建议如何调整它以使用表格行,而不是嵌套,但具有某种用于 css/js 挂钩的类编号层次结构?

<?

//
// Get the data
//
include_once("inc/config.php");

$query = "SELECT c.* 
          FROM categories AS c
          ORDER BY c.id
          LIMIT 1000";          

$result = pg_query($db, $query);

//
// Load all the results into the row array
//
while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC))
{
  //
  // Wrap the row array in a parent array, using the id as they key
  // Load the row values into the new parent array
  //
  $categories[$row['id']] = array(
    'id' => $row['id'], 
    'description' => $row['description'], 
    'parent_id' => $row['parent_id']
  );
}


// print '<pre>';
// print_r($category_array);

// ----------------------------------------------------------------

//
// Create a function to generate a nested view of an array (looping through each array item)
// From: http://68kb.googlecode.com/svn-history/r172/trunk/upload/includes/application/controllers/admin/utility.php
//
function generate_tree_list($array, $parent = 0, $level = 0)
{

  //
  // Reset the flag each time the function is called
  //
  $has_children = false;

  //
  // Loop through each item of the list array
  //
  foreach($array as $key => $value)
  {
    //
    // For the first run, get the first item with a parent_id of 0 (= root category)
    // (or whatever id is passed to the function)
    //
    // For every subsequent run, look for items with a parent_id matching the current item's key (id)
    // (eg. get all items with a parent_id of 2)
    //
    // This will return false (stop) when it find no more matching items/children
    //
    // If this array item's parent_id value is the same as that passed to the function
    // eg. [parent_id] => 0   == $parent = 0 (true)
    // eg. [parent_id] => 20  == $parent = 0 (false)
    //
    if ($value['parent_id'] == $parent) 
    {                   

      //
      // Only print the wrapper ('<ul>') if this is the first child (otherwise just print the item)      
      // Will be false each time the function is called again
      //
      if ($has_children === false)
      {
        //
        // Switch the flag, start the list wrapper, increase the level count
        //
        $has_children = true;  

        echo '<ul class="level-' . $level . '">';

        $level++;
      }

      //
      // Print the list item
      //
      echo '<li><a href="?id=' . $value['id'] . '">' . $value['description'] . '</a>';

      //
      // Repeat function, using the current item's key (id) as the parent_id argument
      // Gives us a nested list of subcategories
      //
      generate_tree_list($array, $key, $level); 

      //
      // Close the item
      //
      echo '</li>';


    }

  }

  //
  // If we opened the wrapper above, close it.
  //
  if ($has_children === true) echo '</ul>';


}

// ----------------------------------------------------------------

//
// generate list
//
generate_tree_list($categories);


?>

【问题讨论】:

    标签: php sql treeview hierarchical-data


    【解决方案1】:

    您可以使用数组创建面包屑视图样式,而无需使用递归函数。

    这是我的工作代码:

    首先,进行如下 SQL 查询:

    $category = CHtml::listData(TblCategory::model()->findAllCategory(array(
    'distinct'=>true,
    'join'=>'LEFT JOIN tbl_category b on b.id = t.cat_parent',
    'join'=>'LEFT JOIN tbl_category c on c.cat_parent = 0',
    'order' => 'cat_name')),'id','cat_name');

    我使用的是yii相关代码,所以你可以使用普通的join查询,然后在foreach()函数中形成一个数组

    public function findAllCategory($condition='',$params=array())
    {
        
        Yii::trace(get_class($this).'.findAll()','system.db.ar.CActiveRecord');
        $criteria=$this->getCommandBuilder()->createCriteria($condition,$params); 
        
        $category = array();
        $cat_before;
        $parent_id = array();
        $cat_before = $this->query($criteria,true); 
        
        //echo "<br><br><br><br><br><br><br>";
        
        foreach($cat_before as $key => $val)
        {
            $category[$key] = $val;
            $parent_id[$key]['cat_parent'] =$val['cat_parent'];
            $parent_id[$key]['cat_name'] =$val['cat_name']; 
            
            foreach($parent_id as $key_1=> $val_1)
            {   
                
                if($parent_id[$key]['cat_parent'] == $category[$key_1]['id'])
                {
                    $category[$key]['cat_name']= $category[$key_1]['cat_name'] .' > '.  $parent_id[$key]['cat_name'];
                    
                }
            }
        } 
        return $cat_before;  
    }

    然后你可以使用Main cat &gt;&gt; subcat 1 &gt;&gt; subcat_1 inner &gt;&gt; ...得到结果

    【讨论】:

      【解决方案2】:
      function generate_list($array,$parent,$level)
      {
      
        foreach ($array as $value)
        {
          $has_children=false;
      
          if ($value['parent_id']==$parent)
          {
      
            if ($has_children==false)
            {
              $has_children=true;
              echo '<ul>';
            }
      
            echo '<li>'.$value['member_name'].' -- '.$value['id'].' -- '.$value['parent_id'];
      
            generate_list($array,$value['id'],$level);
      
            echo '</li>';
          }
      
          if ($has_children==true) echo '</ul>';
      
          echo $value['parent_id'];
        }
      
      }
      

      【讨论】:

        【解决方案3】:

        MySQL 写了一篇关于这个主题的好文章:Managing Hierarchical Data in MySQL

        【讨论】:

        • 我的书签里有这个链接,今天刚刚测试了Oracle删除了这个不错的链接:((
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-07
        相关资源
        最近更新 更多