我半途而废地将所有顶级类别放入 Optgroup,尝试了多种方法,从 stackoverflow 获取了大量引用资料,但未能达到我的要求。
引用here并构建了我的嵌套类别:
function fetchCategoryTree($parent = 0, $spacing = '', $user_tree_array = '') {
global $conn;
if (!is_array($user_tree_array)) {
$user_tree_array = array();
}
$sql = "SELECT `id`, `name`, `parent_id` FROM `acct_categs` WHERE `parent_id` = '".$parent."' ORDER BY `name` ASC";
$query = $conn->Execute($sql);
if (count($query) > 0) {
$current_parent = '';
while ($row = $query->FetchRow()) {
$user_tree_array[] = array("catid" => $row['id'], "catname" => $spacing . $row['name']);
$user_tree_array = fetchCategoryTree($row['id'], $spacing . '- ', $user_tree_array);
}
}
return $user_tree_array;
}
function categoryoption(){
$categoryList = fetchCategoryTree();
$dropdown = '<select name="category_id">';
foreach($categoryList as $cl) {
$dropdown .= "\n<option value=\"".$cl["catid"]."\">".$cl["catname"]."</option>";
}
$dropdown .= "</select>";
return $dropdown;
}
echo categoryoption();
因此,当我回显此内容时,我会得到以下下拉列表:
<select name="category_id">
<option value="91">Assets</option>
<option value="3">- Capital Assets</option>
<option value="23">- - Accum. Amort. -Furn. & Equip.</option>
<option value="25">- - Accum. Amort. -Vehicle</option>
<option value="22">- - Office Furniture & Equipment</option>
<option value="24">- - Vehicle</option>
<option value="1">- Current Assets</option>
<option value="15">- - Accounts Receivables</option>
<option value="16">- - Allowance for doubtful accounts</option>
<option value="13">- - Checking Account</option>
....</select>
我想要的是这样的,https://jsfiddle.net/sbnzp1wL/
<select name="category_id">
<optgroup label="Assets"></optgroup>
<optgroup label="Capital Assets"></optgroup>
<option value="23">- - Accum. Amort. -Furn. & Equip.</option>
<option value="25">- - Accum. Amort. -Vehicle</option>
<option value="22">- - Office Furniture & Equipment</option>
<option value="24">- - Vehicle</option>
<optgroup label="Current Assets"></optgroup>
<option value="15">- - Accounts Receivables</option>
<option value="16">- - Allowance for doubtful accounts</option>
<option value="13">- - Checking Account</option>
<option value="14">- - Petty Cash</option>
....</select>
我读到在 stackoverflow 中的嵌套查询中这是不可能的,但我也从 here 了解到这是可能的.
但是通过该链接帮助,我的顶级类别列出了第二级类别,第二级列出了它的子类别。不知何故,我也没有达到我想要的目标。
我的表值为 here
<小时/>终于让它按照我的需要工作了,如果有人需要它,我将其发布在这里......非常感谢@stj(答案已接受并投票)
$sql = "SELECT `id`, `name`, `parent_id` FROM `acct_categs` ORDER BY `name` ASC";
$query = $conn->Execute($sql);
// build a lookup array with all elements
$all = array();
$hasChildren = array();
while ($row = $query->FetchRow()) {
$all[$row["id"]] = $row;
$hasChildren[$row["parent_id"]] = true;
}
// recursive processing function
function process($rows, $hasChildren, $parentId, $level = 0) {
foreach ($rows as $id => $row) {
if ($row["parent_id"] === $parentId) {
// this is the element we are looking for
$pad = str_repeat(" ", $level);
if (isset($hasChildren[$id])) {
// the element has children
$line = "\n<optgroup label=\"{$row["name"]}\"></optgroup>";
//$line = $pad . $row["id"] . " - " . $row["name"] . " (has children)";
} else {
// the element does not have any children
$line = "\n<option value=\"{$row["id"]}\">{$row["name"]}</option>";
//$line = $pad . $row["id"] . " - " . $row["name"] . " (no children)";
}
// print it
print $line . "\n";
// finally process the children
if (isset($hasChildren[$id])) {
process($rows, $hasChildren, $id, $level + 1);
}
}
}
}
echo '<select name="category_id">';
// start processing
$print = process($all, $hasChildren, "0");
echo $print;
echo '</select>';
最佳答案
您可能正在寻找的是呈现嵌套数据的深度优先递归。
我建议使用单个查询从数据库中查询所有值,并在 PHP 中处理它们。这使您无需发出大量单独的数据库查询(每个元素一个)。
查询完所有相关行后,您可以在 PHP 中递归地遍历它们。 这是一些可以做到这一点的代码。
$sql = "SELECT `id`, `name`, `parent_id` FROM `acct_categs` ORDER BY `name` ASC";
$query = $conn->Execute($sql);
// build a lookup array with all elements
$all = array();
$hasChildren = array();
while ($row = $query->FetchRow()) {
$all[$row["id"]] = $row;
$hasChildren[$row["parent_id"]] = true;
}
// recursive processing function
function process($rows, $hasChildren, $parentId, $level = 0) {
foreach ($rows as $id => $row) {
if ($row["parent_id"] === $parentId) {
// this is the element we are looking for
$pad = str_repeat(" ", $level);
if (isset($hasChildren[$id])) {
// the element has children
$line = $pad . $row["id"] . " - " . $row["name"] . " (has children)";
}
else {
// the element does not have any children
$line = $pad . $row["id"] . " - " . $row["name"] . " (no children)";
}
// print it
print $line . "\n";
// finally process the children
if (isset($hasChildren[$id])) {
process($rows, $hasChildren, $id, $level + 1);
}
}
}
}
// start processing
process($all, $hasChildren, 0);
请注意,它不会打印嵌套的 optgroup。原因是我不确定 optgroups 应该去哪里。我认为 optgroup 元素不应该嵌套。但如果你真的想这样做,那就继续吧。
此外,您可能需要根据需要调整填充 $line
的代码部分。
关于php - 将 PHP MYSQL 中类别表中的所有顶级类别作为 Optgroup,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29709645/