PHP从4个数组制作树状结构数组

标签 php json algorithm

我在页面上有类别(表示为复选框)。在下一页上,我有第一页类别的子类别。在下一页上,第二页中元素的子类别等等。我将所有选定的项目保存在数组中,代表在不同级别所做的选择。问题是我不知道如何从所有这些数组制作树结构。让我说一下我目前的情况:

我有 4 个数组,让我们将它们想象成 4 个级别(每个级别代表在 # 页面上选中的复选框)。我将用户选择的复选框保存在其中。下面是一个数据的例子:(值代表数据库中item的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(例如:级别 2:)

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

我可以通过查询数据库找到关系。

在上面的例子中,来自 l2 的两个元素都是 l1[0] 的子类别。 第 3 级的前 2 个元素是 l2[0] 的子类别,最后 2 个元素是 l2[1] 的子类别,在第 4 级中,其中一些元素是第 3 级中某些内容的子类别(并非每个元素都可能有子类别)。

如何为所有这些数据构建树状结构的 JSON?有什么想法或建议吗?谢谢!

最佳答案

首先,如果我没有很好地理解你的问题,请道歉。

让我用我理解的方式解释你的问题:

首页

您显示一个表单,其中包含名称为“类别”的复选框,值是特定主要类别的 ID

在第二页登陆

你用检查类别填充一个数组(我称之为 $_SESSION['categories_checked'])

在第二页

您显示级别 1 的子类别的方式与您在主页上显示类别的方式相同。假设表单元素名称是“subcat1”

在第三页登陆

你用检查子类别填充一个数组(我称之为 $_SESSION['subcats1_checked'])

在第三页

您显示级别 2 的子类别的方式与您在主页上显示类别的方式相同。假设表单元素名称是“subcat2”

在第四页登陆

你用检查子类别填充一个数组(我称之为 $_SESSION['subcats2_checked'])

第四页

您显示级别 3 的子类别的方式与您在主页上显示类别的方式相同。假设表单元素名称是“subcat3”

在最终页面着陆时

你用检查子类别填充一个数组(我称之为 $_SESSION['subcats3_checked'])

我的回答

从我的角度来看,我宁愿做以下事情:

  • 总是使用相同的变量名(在 HTML 表单和 PHP 中),这样代码可以大大改进
  • 可选地使用隐藏的表单元素,其中包含级别
  • 嵌套数组

    $_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 查询的单页解决方案。

关于PHP从4个数组制作树状结构数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44284491/

相关文章:

javascript - 获取值最接近数字 X 的 JSON 数据

java - 包含所有字母的不同字符的最短子字符串的长度

php - 如何从 PHP 中的 UTF8 字符获取 "remove diacritics"?

javascript - Jquery 验证中最多允许 10 封电子邮件,每个电子邮件以逗号分隔

php - 使用 cookie 显示用户在 PHP 中访问网站的次数

json - 在 SAPUI5 中显示嵌套的 JSON 数据(sap.m 表)

php - 如何在 wp_nav_menu 中添加类以链接?

php - JSON 为空,而数据库不为空

python - 在 Python 中使用中序和前序遍历重建树

algorithm - 有一个 int I 和 number if iterations 和一个函数 DrawPoint(x,y) 如何画一个圆?