PHP将4个数组转换为树形结构数组

3
我在一个页面上有分类(用复选框表示)。在下一页上,我有来自第一页类别的子类别。在第二页中,我有元素的子类别,以此类推。我将所有选择的项目保存在数组中,这些数组代表不同级别的选择。问题是我不知道如何从所有这些数组中创建树形结构。让我说一下我目前拥有的东西:
我有4个数组,把它们想象成4个级别(每个级别表示在#页面上选择的复选框)。我在这些数组中保留用户选择的复选框。以下是数据示例:(值表示数据库中该项的ID)
The l1 value of $_SESSION['0'] is '1' 

The l2 value of $_SESSION['0'] is '2' 
The l2 value of $_SESSION['1'] is '3' 

The l3 value of $_SESSION['0'] is '3' 
The l3 value of $_SESSION['1'] is '4' 
The l3 value of $_SESSION['2'] is '5' 
The l3 value of $_SESSION['3'] is '6' 

The l4 value of $_SESSION['0'] is '1' 
The l4 value of $_SESSION['1'] is '2' 
The l4 value of $_SESSION['2'] is '3' 
The l4 value of $_SESSION['3'] is '4' 
The l4 value of $_SESSION['4'] is '5' 

对于数据库中的每个id,我都有它所属项目的id(例如:level 2:)

id=1; name = programming, category_id = 1;

我可以通过查询数据库来找到关系。
上述情况中,l2中的两个元素都是l1[0]的子类别。来自第3层的前两个元素是l2[0]的子类别,最后两个元素是l2[1]的子类别,在第4层中,它们中的一些是第3层中某个东西的子类别(并非每个元素都可能有子类别)。
如何为所有这些数据构建树形结构的JSON?您有什么想法或建议吗?谢谢!

这个问题与JSON无关。你需要使用本地PHP数据结构(数组、对象)来创建你的“树形结构”,然后,如果你想要一个JSON版本,可以使用json_encode进行序列化。 - JAAulde
我知道问题所在,但是我不知道如何做树形结构。 - Andrew T
我理解您的意思。我的观点是,您一直在谈论JSON,并将问题标记为JSON。如果您想得到好的帮助,请将问题集中在真正的问题上。 - JAAulde
谢谢!我现在会编辑问题。 - Andrew T
1个回答

1
首先,请原谅我如果我没有正确理解您的问题。
让我用我理解的方式来解释您的问题: 第一页 您展示了一个包含复选框的表单,其名称为“category”,值为特定主类别的ID。 第二页降落 您用选中的类别填充了一个数组(我会称之为$_SESSION['categories_checked'])。 第二页 您以与在主页上显示类别相同的方式显示一级子类别。假设表单元素名称为“subcat1”。 第三页降落 您用选中的子类别填充了一个数组(我会称之为$_SESSION['subcats1_checked'])。 第三页 您以与在主页上显示类别相同的方式显示二级子类别。假设表单元素名称为“subcat2”。 第四页降落 您用选中的子类别填充了一个数组(我会称之为$_SESSION['subcats2_checked'])。 第四页 你可以像在主页面上展示类别一样展示三级子类别,表单元素名称为 "subcat3"。
在最终页面着陆时,你可以使用选中的子类别来填充数组(我会称其为 $_SESSION['subcats3_checked'])。
从我的角度来看,我更倾向于执行以下操作:
  • always use same variable name (in HTML forms and in PHP) so the code could be greatly improved
  • optionnaly use a hidden form element which would contain the level
  • nest your arrays

    $_SESSION['categories'] = [
          3 => [
                56 => [
                     89 => [
                           121 => [1,2,3,4,5,],
                           ],
                      ],
               ],
    ];
    
这种表现方式更贴近实际情况,应该更容易显示。
下一步是创建一个递归函数,在其中传递一个步骤表单的结果数组和 $_SESSION['categories'] 变量。
如果这个解决方案适合您,请告诉我... 如果需要,我可以帮助您。
所以,递归是成功的关键,但是还有一些缺失...为了处理您的结果并获得我提到的 PHP 数组,您必须以以下方式构建您的表单:
第一页
<input type="checkbox" name="category[0]" value="1" /> Cat1 name
<input type="checkbox" name="category[0]" value="2" /> Cat2 name

第二页。
Subcats of cat 1
<input type="checkbox" name="category[1]" value="110" /> SubCat1 name
<input type="checkbox" name="category[1]" value="222" /> SubCat2 name

Subcats of cat 2
<input type="checkbox" name="category[2]" value="110" /> SubCat1 name
<input type="checkbox" name="category[2]" value="222" /> SubCat2 name

这样,您就可以避免级别输入元素,因为子类现在仅由其父类定义。当然,这意味着每个类别和子类别都有不同的ID(如果不是这种情况,则可能会出现技巧)。
这里是一个快速而简单的代码,应该能帮助您。
<?php
/**
 * Created by PhpStorm.
 * User: dvienne
 * Date: 31/05/2017
 * Time: 15:16
 */
function treatCategories($parentCatId, $selectedId, $categories) {
  foreach($categories as $categoryID => $category) {
    if(empty($category) AND ($categoryID==$parentCatId)) {
      $categories[$categoryID][$selectedId] = [];
      break;
    } elseif(is_array($category) AND empty($category)) {
      /** RECURSION */
      treatCategories($parentCatId, $selectedId, $category);
    }
  }

  $_SESSION['categories'] = $categories;
}


$userSelection  = $_POST['categories'];
$level          = $_POST['level'];
if(!empty($_SESSION['categories'])) {
  $categories = $_SESSION['categories'];
} else {
  $categories = [];
}

if(!empty($categories)) {
  foreach($userSelection as $parentCatId => $selectedId) {
    treatCategories($parentCatId, $selectedId, $categories);
  }
} else {
  foreach($userSelection as $catId) {
    $categories[$catId] = [];
  }

  $_SESSION['categories'] = $categories;
}

请注意

这显然不是一种优化处理数据的方式,因为脚本必须在插入其值之前扫描整个类别数组。您可以考虑使用 AJAX 查询的单页解决方案。


你理解得很正确!我知道我必须写一个递归函数,但我不知道该怎么做。我可能需要建立30到40个数组。我看不出解决这个问题的最优方法。 - Andrew T
我不知道从哪里开始。为了让你更清楚,在数据库中的第4个表中,我有关系ID到第3级。 - Andrew T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接