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