我试图在我的应用中列出具有子类别的类别 - 我可以使用PHP或Javascript / Jquery进行以下操作:
我有一个类别数组,附加了子类别作为附加数组
诀窍在于它可以像子类别那样深入。 和子类别也可以有子类别。
因此,对于每个类别,它可以拥有尽可能多的孩子,每个孩子可以拥有许多子阵列。
循环创建下拉列表的最佳方法是什么?
这是转储主数组时的结构:
array (size=2)
0 =>
array (size=4)
'id' => int 1
'name' => string 'Stationery' (length=10)
'parent_id' => int 0
'childs' =>
array (size=1)
0 =>
array (size=4)
...
1 =>
array (size=3)
'id' => int 4
'name' => string 'boots' (length=5)
'parent_id' => int 0
通知子零有一个"孩子"排列 当转储这个数组时,我得到:
array (size=1)
0 =>
array (size=4)
'id' => int 2
'name' => string 'pens' (length=4)
'parent_id' => int 1
'childs' =>
array (size=1)
0 =>
array (size=4)
...
请注意,这也有附加的子项,在转储时看起来像:
array (size=1)
0 =>
array (size=4)
'id' => int 3
'name' => string 'penfillers' (length=10)
'parent_id' => int 2
'childs' =>
array (size=1)
0 =>
array (size=3)
...
偷偷摸摸 - 这个还有另一个孩子!
这可以像子类别一样深入
我如何循环浏览它们并将输出放在下拉列表中? 我很难过如何无限循环直到链条结束。
由于 杰森
答案 0 :(得分:1)
您应该递归地生成数组中的所有选项。有两种方法可以实现它。取决于您的PHP版本。
为了使核心逻辑更清晰,假设我们使用这些实用程序渲染输出:
//
// some function to tidy up outputs
//
// simply make the recursive level visible
function pad_level($string, $level) {
// no pad for 0 level
if ($level == 0) return $string;
// pad some '-' to show levels
$pad = str_repeat('-', $level);
return $pad . ' ' . $string;
}
// render a leaf into standardized info array for an option
function option_from($item, $level) {
return array(
'value' => $item['id'],
'display_value' => pad_level($item['name'], $level),
);
}
// render options into HTML select
function render_select($name, $options) {
$output = '';
foreach ($options as $option) {
$output .= ' '.
'<option value="'.htmlspecialchars($option["value"]).'">'.
htmlspecialchars($option["display_value"]).
'</option>'."\n";
}
return '<select name="'.htmlspecialchars($name).'">'."\n".
$output."</select>\n";
}
// render options into plain text display
function render_plain_text($name, $options) {
$output = '';
foreach ($options as $option) {
$output .= $option["value"].' => '.$option["display_value"]."\n";
}
return $output;
}
这是两种方法:
//
// core logic
//
// Method 1: Generator. Available with PHP 5 >= 5.5.0
function options_in($array, $level=0) {
foreach ($array as $leaf) {
yield option_from($leaf, $level);
// yield the children options, if any
if (isset($leaf['childs']) && is_array($leaf['childs'])) {
foreach (options_in($leaf['childs'], $level+1) as $option) {
yield $option;
}
}
}
}
// Method 2: Normal recursion then merge arrays. For PHP 4 or after
function get_options($array, $level=0) {
$output = array();
// yield for the option array
foreach ($array as $leaf) {
$output[] = option_from($leaf, $level);
// yield the children
if (isset($leaf['childs']) && is_array($leaf['childs'])) {
$childs = get_options($leaf['childs'], $level+1);
$output = array_merge($output, $childs); // this could be slow
}
}
return $output;
}
这就是你实际渲染HTML的方法:
// dummy input
$input = array(
array(
'id' => 1,
'name' => 'Stationery',
'parent_id' => 0,
'childs' => array(
array(
'id' => 2,
'name' => 'Pencil',
'parent_id' => 1,
),
array(
'id' => 3,
'name' => 'Pen',
'parent_id' => 1,
),
array(
'id' => 5,
'name' => 'Notepad',
'parent_id' => 1,
'childs' => array(
array(
'id' => 8,
'name' => 'Blue Pad',
'parent_id' => 3,
),
array(
'id' => 9,
'name' => 'Red Pad',
'parent_id' => 3,
),
array(
'id' => 10,
'name' => 'iPad',
'parent_id' => 3,
),
),
),
),
),
array(
'id' => 4,
'name' => 'boots',
'parent_id' => 0,
),
);
// method 1, preferred
echo "\nMethod 1\n";
echo render_select('mySelect', options_in($input));
echo render_plain_text('mySelect', options_in($input));
// method 2
echo "\nMethod 2\n";
echo render_select('mySelect', get_options($input));
echo render_plain_text('mySelect', get_options($input));
答案 1 :(得分:1)
这是一个非常简单的示例,说明如何使用递归来完成它。我确信有更好的方法,但这是一个非常简单的功能,所以你可以看到这个概念。该函数调用自己直到作业完成(我在这里使用方括号数组表示法,所以请确保您的PHP版本支持它)
<?php
function getItems(array $items)
{
$return = [];
foreach ($items as $item) {
$return[] = $item;
if (isset($item['childs']) && count($item['childs']) > 0) {
$return = array_merge(
$return,
getItems($item['childs'])
);
}
}
return $return;
}
$array = [
0 => [
'id' => 1,
'childs' => []
],
1 => [
'id' => 2,
'childs' => [
0 => [
'id' => 3,
'childs' => []
]
]
]
];
print_r(getItems($array));
然后循环结果以创建您的选择选项。希望这有帮助
答案 2 :(得分:0)
创建一个子函数,子函数的输入将是对象,此函数将检查它是一个数组还是一个简单元素,如果它是一个数组,那么它将在该元素上再次调用该函数,否则返回该元素。 只是精心制作&#34; Gerald Schneider的回答。