嵌套行加入

时间:2012-10-24 16:34:22

标签: php nested

请在简洁的PHP类型代码中提供以下问题的简单解决方案(只需要松散地遵循PHP类型语法):

我们希望能够输出嵌套的项目列表 - 列表中的项目可以是列表中其他项目的子项目。一个简单的SQL表将包含以下字段:

  1. itemID - int。
  2. item - varchar。
  3. subItemOfID - int。
  4. 一小部分数据看起来像这样:

    itemID  item    subItemOfID
    1   Item1   0
    2   Item2   0
    3   Item3   0
    4   Item10  1
    5   Item11  1
    6   Item12  1
    7   Item100 4
    8   Item101 4
    9   Item102 4
    10  Item30  3
    11  Item31  3
    12  Item32  3
    

    输出需要看起来像这样(嵌套列表按项目排序):

    •   Item1
        o       Item10
               Item100
               Item101
               Item102
        o       Item11
        o       Item12
    •   Item2
    •   Item3
        o       Item30
        o       Item31
        o       Item32
    

    如果SubItemOfID行按降序排列,我会得到这个,但我之前使用的例子在项目上有一个正则表达式,我总是被告知这是一种用表做事情的坏方法,因为varchars可以改变。我需要帮助!这就是我到目前为止所做的:

    <?php
    $table = array (
    'itemID' => array( 
                        1,2,3,4,5,6,7,8,9,10,11,12
                    ),
    'item' => array(
                        'Item1','Item2','Item3','Item10','Item11','Item12','Item100','Item101','Item102','Item30','Item31','Item32'
                    ),
    'subItemOfID' => array(
                        0,0,0,1,1,1,4,4,4,3,3,3
                    )
                    );
    
    foreach($table as $header => $column) {
        foreach($column as $data) {
            if($header == 'item') {
                $fixed = intval(str_replace('Item','',$data));      
                $str_len = strlen($fixed);
                echo '<ul>';
                if($str_len === 1) {
                    echo '<li>'.$data.'</li>';
                }
                echo '<ul>';
                if($str_len === 2  ) {
                    echo '<li>'.$data.'</li>';              
                }
                echo'<ul>';
                if($str_len ===3) {
                    echo '<li>'.$data.'</li>';
                }
                echo '</ul>';
                echo '</ul>';
                echo '</ul>';       
            }
        }
    }
    ?>
    enter code here
    

1 个答案:

答案 0 :(得分:0)

使用此查询,您最多可以获取6个类别:

$sql = "SELECT c1.item AS item,
              IF(c6.item IS NOT NULL, 6,
                  IF(c5.item IS NOT NULL, 5,
                     IF(c4.item IS NOT NULL, 4,
                        IF(c3.item IS NOT NULL, 3,
                           IF(c2.item IS NOT NULL, 2, 1))))) AS lvl,
              if (c6.item IS NOT NULL, CONCAT(c6.itemId, c5.itemId, c4.itemId, c3.itemId, c2.itemId, c1.itemId),
                  IF(c5.item IS NOT NULL, CONCAT(c5.itemId, c4.itemId, c3.itemId, c2.itemId, c1.itemId),
                     IF(c4.item IS NOT NULL, CONCAT(c4.itemId, c3.itemId, c2.itemId, c1.itemId),
                        IF(c3.item IS NOT NULL, CONCAT(c3.itemId, c2.itemId, c1.itemId),
                           IF(c2.item IS NOT NULL, CONCAT(c2.itemId, c1.itemId), c1.itemId))))) AS code,
       FROM categories c1
       LEFT JOIN categories c2 ON c2.itemId = c1.subItemOfID
       LEFT JOIN categories c3 ON c3.itemId = c2.subItemOfID
       LEFT JOIN categories c4 ON c4.itemId = c3.subItemOfID
       LEFT JOIN categories c5 ON c5.itemId = c4.subItemOfID
       LEFT JOIN categories c6 ON c6.itemId = c5.subItemOfID
       GROUP BY c1.itemId
       ORDER BY code";
$q = mysql_query($sql);
while (false !== ($row = mysql_fetch_assoc($q))) {
    echo str_repeat('---', $row['lvl'])
       . $row['title']
       . '<br />';
}

它做什么:选择每个类别及其父类别(如果存在),然后生成代码字段以对它们进行排序。

对不起,我不经意地读了这个问题。

这是php中的解决方案:

$table = array (
    'itemID' => array(
        1,2,3,4,5,6,7,8,9,10,11,12
    ),
    'item' => array(
        'Item1','Item2','Item3','Item10','Item11','Item12','Item100','Item101','Item102','Item30','Item31','Item32'
    ),
    'subItemOfID' => array(
        0,0,0,1,1,1,4,4,4,3,3,3
    )
);
outputChildrenRecursive(0, $table);

/**
 * Outputs child items recursively
 *
 * @param integer $parentItemID Parent item itemID
 * @param array   $table        Table data
 */
function outputChildrenRecursive($parentItemID, array $table)
{
    // Get children
    $children = array();
    foreach ($table['itemID'] as $key => $value) {
        if ($table['subItemOfID'][$key] == $parentItemID) {
            $children[] = $key;
        }
    }

    // Output children and grandchildren
    if (!empty($children)) {
        echo '<ul>';
        foreach ($children as $childKey) {
            echo '<li>';
            echo $table['item'][$childKey];
            // Prevent infinite recursion if itemID equals subItemOfID
            if ($table['itemID'][$childKey] != $table['subItemOfID'][$childKey]) {
                outputChildrenRecursive($table['itemID'][$childKey], $table);
            }
            echo '</li>';
        }
        echo '</ul>';
    }
}