代码之家  ›  专栏  ›  技术社区  ›  meleyal

如何用PHP/SQL构建树视图?

  •  2
  • meleyal  · 技术社区  · 16 年前

    最好的方法是:

    我的桌子有 id , name parent_id 柱。


    这里是我最后一个答案的更新,有一个计数器给每个ul一个嵌套的“level”类,还有一些注释。

    有人能建议如何调整它以使用表行,而不嵌套,而是使用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);
    
    
    ?>
    
    3 回复  |  直到 13 年前
        1
  •  4
  •   Cosmin    13 年前
    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'];
      }
    
    }
    
        2
  •  2
  •   ThoKra    16 年前
        3
  •  0
  •   pistou    9 年前

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

    这是我的工作代码:

    首先,进行如下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');

    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 >> subcat 1 >> subcat_1 inner >> ...