【问题标题】:Creating a multidimensional array tree from MySQL table in PHP在 PHP 中从 MySQL 表创建多维数组树
【发布时间】:2013-12-14 23:01:04
【问题描述】:

我正在尝试将我的 mysql 表组织成一个多维 php 树数组。

例如,我试图将我的产品组织在一个层次结构中以便于选择,从而缩小结果范围。

我返回的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
)

...等

注意最后一个数组值是产品 ID。

我正在寻求帮助编写一个递归函数,该函数将生成一个如下所示的数组:

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
                  )
              )
         )

    )
)

我尝试过类似的方法:

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

            }
        }
    }
}

【问题讨论】:

  • “寻求帮助” .. 请告诉我们您已经尝试过什么以及失败的地方
  • 欢迎来到 StackOverflow!我们不是来为您编写代码,我们是来帮助您修复您尝试过的错误。在这种情况下,要获得任何帮助,您至少需要告诉我们这些数组是如何链接在一起的——一堆数字键没有任何意义。
  • 对不起!就像我说的,我正在查询将产品信息存储在表中的数据库。 id 是数据库中的产品 id。上面编辑的帖子。
  • 您的层次结构根本不考虑第 5 个元素。
  • 我发布的示例行只是一张大表的一小部分。有时它们会有值,否则它们将是空白的并且不被考虑。不同的产品有时有不同的类别。

标签: php mysql arrays multidimensional-array


【解决方案1】:

我认为你的代码有一个好的意图:使用$level 来保持当前深度。但目前这行不通,因为您正在通过$level = $data[$row[$i-1]]; 复制 - 而您需要refer to it,例如$level =&amp; $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 基本上可以,您需要两行代码:获取数组的第一个元素,然后将其删除。然后我将计数的结果保存在一个变量中,这样就不需要在forwhile 的每次迭代中重新计算。

另外我建议手动设置$maxIterator。对于显示的结果,一个好的默认值是5。这样所有值在 5 号之前。将用于嵌套,第 5 个本身将用于计数(在您的示例中,这是存储大小)。

由于for 将在最后一次迭代后执行$i++(然后它使条件失败,因此循环中断),它可以用于计数。


就我个人而言,我会过度思考您到底在做什么,并且可能会为此使用特定的结构。但是,这段代码应该会给您一个很好的印象,它是如何使用引用来解决的。

【讨论】:

  • 谢谢!但是,我认为 break 语句过早结束循环并且没有达到其他值,例如容量。它在屏幕尺寸后立即切断。有没有办法让它忽略空白值并跳到下一个循环?
  • 谢谢您的好心先生!不知道这是一个选择。
猜你喜欢
  • 1970-01-01
  • 2018-05-30
  • 1970-01-01
  • 1970-01-01
  • 2016-12-07
  • 2019-12-04
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多