简体   繁体   English

在PHP中从MySQL表创建多维数组树

[英]Creating a multidimensional array tree from MySQL table in PHP

I'm trying to organize my mysql table into a multidimension php tree array. 我试图将我的mysql表组织成一个多维php树数组。

For example, I'm trying to organize my products in a hierarchy for easy selection to narrow down the result the narrower they go in the result. 例如,我正在尝试将我的产品按层次结构进行组织,以便于选择,以缩小结果范围。

I am returned mysql rows like this: 我返回了这样的mysql行:

Array
(
    [1] => Amazon
    [2] => Kindle Fire
    [3] => 
    [4] => 
    [5] => 
    [6] => 
    [7] => 
    [8] => 
    [9] => 1
)
Array
(
    [1] => Amazon
    [2] => Kindle Fire HD
    [3] => WiFi
    [4] => 7"
    [5] => 
    [6] => 16GB
    [7] => 
    [8] => 
    [9] => 2
)
Array
(
    [1] => Amazon
    [2] => Kindle Fire HD
    [3] => WiFi
    [4] => 7"
    [5] => 
    [6] => 32GB
    [7] => 
    [8] => 
    [9] => 3
)
Array
(
    [1] => Amazon
    [2] => Kindle Fire HD
    [3] => WiFi
    [4] => 8.9"
    [5] => 
    [6] => 16GB
    [7] => 
    [8] => 
    [9] => 4
)
Array
(
    [1] => Amazon
    [2] => Kindle Fire HD
    [3] => WiFi
    [4] => 8.9"
    [5] => 
    [6] => 32GB
    [7] => 
    [8] => 
    [9] => 5
)
Array
(
    [1] => Amazon
    [2] => Kindle Fire HD
    [3] => 4G LTE
    [4] => 8.9"
    [5] => 
    [6] => 32GB
    [7] => 
    [8] => 
    [9] => 6
)
Array
(
    [1] => Amazon
    [2] => Kindle Fire HD
    [3] => 4G LTE
    [4] => 8.9"
    [5] => 
    [6] => 64GB
    [7] => 
    [8] => 
    [9] => 7
)
Array
(
    [1] => Amazon
    [2] => Kindle Fire HDX
    [3] => Wifi
    [4] => 7"
    [5] => 
    [6] => 16GB
    [7] => 
    [8] => 
    [9] => 8
)
Array
(
    [1] => Amazon
    [2] => Kindle Fire HDX
    [3] => Wifi
    [4] => 7"
    [5] => 
    [6] => 32GB
    [7] => 
    [8] => 
    [9] => 9
)
Array
(
    [1] => Amazon
    [2] => Kindle Fire HDX
    [3] => Wifi
    [4] => 7"
    [5] => 
    [6] => 64GB
    [7] => 
    [8] => 
    [9] => 10
)

...etc ...等等

Note the last array value is the Product ID. 请注意,最后一个数组值是产品ID。

And I'm looking for help writing a recursive function that will result in an array that looks like: 我正在寻找编写递归函数的帮助,该递归函数将导致数组如下所示:

Array(
    'Amazon' => Array(
         'Kindle Fire' => 1,
         'Kindle Fire HD' => Array(
              'WiFi' => Array(
                  '7"' => Array(
                      '16GB' => 2,
                      '32GB' => 3
                  )
                  '8.9"' => Array(
                      '16GB' => 4,
                      '32GB' => 5
                  )
              )
         )

    )
)

I've tried something like: 我已经尝试过类似的东西:

while($row = mysqli_fetch_row($res)) {
    $id = $row[0];
    unset($row[0]);
    unset($row[count($row)]);
        $row[] = $id; // Moves id to last array value

    for($i = 1; $i < count($row); $i++) {
        if($i == 1) {
            if(!array_key_exists($row[$i], $data)) {
                // Insert key
                $data[$row[$i]] = array();
            }
        }
        else {
            $level = $data[$row[$i-1]];

            if(array_key_exists($row[$i], $level)) {
                // Key exists
            }
            else {
                // Insert key

            }
        }
    }
}

I think your code has a good intention: using $level to hold the current depth. 我认为您的代码具有良好的意图:使用$level保持当前深度。 But at the moment this won't work, because you are copying via $level = $data[$row[$i-1]]; 但是目前这还行不通,因为您是通过$level = $data[$row[$i-1]];复制的$level = $data[$row[$i-1]]; - instead you need to refer to it , eg with $level =& $data[$row[$i-1]]; -相反,您需要引用它 ,例如$level =& $data[$row[$i-1]]; .

$result = array();
while ($row = mysqli_fetch_row($res)) [
    $id = array_shift($row);

    if (!isset($maxIterator))
        $maxIterator = count($row)-1;

    $current =& $result;
    for ($i=0; $i<$maxIterator; $i++) {
        if (empty($row[$i]))
            break;
        if (!array_key_exists($row[$i], $current))
            $current[ $row[$i] ] = array();
        $current =& $current[ $row[$i] ];
    }
    //for properly ended and wasn't broken out of sooner
    if ($i == $maxIterator) {
        if (!array_key_exists($row[$i], $current))
            $current[ $row[$i] ] = 1;
        else
            $current[ $row[$i] ]++;
    }
}

array_shift basically does, what you needed two lines for: get the first element of an array and then remove it. array_shift基本上可以做到,您需要两行来完成:获取数组的第一个元素,然后将其删除。 Then I save the result of the count in a variable, so it doesn't need to be recalculated in every iteration of the for AND while . 然后,我将计数结果保存在一个变量中,因此不需要在for AND while每次迭代中都重新计算它。

Also I would suggest setting $maxIterator manually. 另外我建议手动设置$maxIterator With the shown result a good default would be 5 . 根据显示的结果,一个很好的默认值为5 This way all values before the 5th. 这样所有值在5号之前。 will be used for nesting and the 5th itself will be used to count (in your example this is storage size). 将用于嵌套,第五位本身将用于计数(在您的示例中,这是存储空间)。

As the for will execute $i++ after the last iteration (and then it fails the condition and hence the loop breaks), it can be used for the counting. 因为for将在最后一次迭代后执行$i++ (然后它使条件失败并因此导致循环中断),因此可以将其用于计数。


Personally I would overthink what exactly you are doing and maybe use a specifc structure for that. 我个人会过分考虑您到底在做什么,并且可能为此使用特定的结构。 However, this code should give you a good impression how it can be solved using references. 但是,此代码应给您一个很好的印象,即如何使用引用来解决它。

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

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