php - 将 PHP MYSQL 中类别表中的所有顶级类别作为 Optgroup

标签 php mysql nested

我半途而废地将所有顶级类别放入 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">-&nbsp;Capital Assets</option>
<option value="23">-&nbsp;-&nbsp;Accum. Amort. -Furn. &amp; Equip.</option>
<option value="25">-&nbsp;-&nbsp;Accum. Amort. -Vehicle</option>
<option value="22">-&nbsp;-&nbsp;Office Furniture &amp; Equipment</option>
<option value="24">-&nbsp;-&nbsp;Vehicle</option>
<option value="1">-&nbsp;Current Assets</option>
<option value="15">-&nbsp;-&nbsp;Accounts Receivables</option>
<option value="16">-&nbsp;-&nbsp;Allowance for doubtful accounts</option>
<option value="13">-&nbsp;-&nbsp;Checking Account</option>
....</select>

我想要的是这样的,https://jsfiddle.net/sbnzp1wL/

<select name="category_id">
<optgroup label="Assets"></optgroup>
<optgroup label="Capital Assets"></optgroup>
<option value="23">-&nbsp;-&nbsp;Accum. Amort. -Furn. &amp; Equip.</option>
<option value="25">-&nbsp;-&nbsp;Accum. Amort. -Vehicle</option>
<option value="22">-&nbsp;-&nbsp;Office Furniture &amp; Equipment</option>
<option value="24">-&nbsp;-&nbsp;Vehicle</option>
<optgroup label="Current Assets"></optgroup>
<option value="15">-&nbsp;-&nbsp;Accounts Receivables</option>
<option value="16">-&nbsp;-&nbsp;Allowance for doubtful accounts</option>
<option value="13">-&nbsp;-&nbsp;Checking Account</option>
<option value="14">-&nbsp;-&nbsp;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/

相关文章:

php - 全文搜索得分相关性分析

javascript - 使用函数式编程获取 "TypeError: undefined is not a function"

cuda - 在我的程序中分配统一内存。运行后,它抛出 CUDA 错误 :out of memory, 但仍有可用内存

php - Symfony 2.8 和 PHP 7.4 : Warning: "continue" targeting switch is equivalent to "break". Composer 是最新版本

Mysql select - 提高性能

php - 语法错误或访问冲突 : 1064 You have an error in your SQL syntax;

mysql - 将个人明文密码存储在私有(private) mysql 数据库中安全吗?

javascript - 进入对象或对象的对象的条目和键

php - 是否可以使用 ajax/jquery 技术预加载页面内容?

javascript - 制作日历的问题