Php 创建包含父子菜单项的多选下拉列表
我计划在php中创建一个多选下拉列表或多选复选框表单元素。但具有父子菜单项关系 例如:我有三个单独的表tbl_branch、tbl_area、tbl_region和另外两个表用于映射tbl_region area和tbl_area ToBranch。现在我需要一个多选或多选复选框,它看起来像这样:Php 创建包含父子菜单项的多选下拉列表,php,mysql,html,arrays,Php,Mysql,Html,Arrays,我计划在php中创建一个多选下拉列表或多选复选框表单元素。但具有父子菜单项关系 例如:我有三个单独的表tbl_branch、tbl_area、tbl_region和另外两个表用于映射tbl_region area和tbl_area ToBranch。现在我需要一个多选或多选复选框,它看起来像这样: Branch 1 Area 1 Region 1 Region 2 Area 2 Region 3 Region 4 Region 7 Region 9 Ar
Branch 1
Area 1
Region 1
Region 2
Area 2
Region 3
Region 4
Region 7
Region 9
Area 5
Area 7
Region 8
Branch 2
Area 3
Branch 3
Branch 4
Branch 5
Area 6
Region 10
Area 2
因此,正如您所猜测的,分支是层次结构中最顶层,区域是最底层,即分支是父级。我想让它循环,直到它找到它的孩子。一旦停止查找任何子项,它将转到数组中的下一个父项
我对数组和形成复杂的sql查询非常不在行,因此我希望在如何实现这一点上有一些开始方向。如果有人能帮我,我会非常感激的
提前谢谢我建议您阅读一下 我已经建立了一个几乎相同的数据树,并且使用上面文档中建议的方法使问题变得非常简单,特别是当涉及到确定低至n个水平的父母和兄弟姐妹时 简短的版本是在每个节点的“左”和“右”上分配一个数字,然后使用该数字可以非常有效地选择树的段。那篇文章中有一个更冗长的版本,它的解释比我所能解释的要彻底得多,并且包含了有用的MySQL代码 这是主表的潜在轮廓
treeTable (
// ID field
id INT UNSIGNED PK AI,
// Fields for branching
lft INT UNSIGNED,
rgt INT UNSIGNED,
// ID fields for the specific types
leafType ENUM('Branch','Area','Region'),
leafID INT UNSIGNED,
leafName VARCHAR
)
UNIQUE INDEX (leafType,leafID)
如果您需要每种类型的特定数据,那么您可以为它们创建单独的表,但上面的内容可以让您创建树,映射出id,并允许将关系与显示名称一起存储
当然,每个叶型之间的标准化数据越多越好,理想情况下,它们实际上都是相同类型的数据,因为它们都是地理分区
以您的数据样本为例
Branch 3
Branch 4
Branch 5
Area 6
Region 10
Area 2
您可能最终会得到如下表格:
id lft rgt leafType leafID
1 1 2 'Branch' 3
2 3 4 'Branch' 4
3 5 12 'Branch' 5
4 6 9 'Area' 6
5 7 8 'Region' 10
6 10 11 'Area' 2
有关如何插入etc的查询可在链接文章中找到,即(逐字引用自)
然后一个SELECT可以显示树(同样是源代码中的逐字)
当然,上面2中的字段/表名是不变的,但您可以根据需要更新表/字段名
在我的最新评论之后,下面是用于插入新行的存储过程的定义
CREATE PROCEDURE `addOptionalExtraToTree`(inParentOptionID INT,inOptionName VARCHAR(40),inLeafType VARCHAR(20))
BEGIN
DECLARE myRight INT UNSIGNED DEFAULT 0;
SELECT optionalExtra_tree_right-1
INTO myRight
FROM optionalExtras
WHERE optionalExtraID = inParentOptionID;
IF myRight = 0 THEN
SELECT COALESCE(MAX(optionalExtra_tree_right),0)
INTO myRight
FROM optionalExtras;
END IF;
UPDATE optionalExtras
SET optionalExtra_tree_right = optionalExtra_tree_right + 2
WHERE optionalExtra_tree_right > myRight;
UPDATE optionalExtras
SET optionalExtra_tree_left = optionalExtra_tree_left + 2
WHERE optionalExtra_tree_left > myRight;
INSERT INTO optionalExtras (
optionalExtra_name,
optionalExtra_leaf_type,
optionalExtra_tree_left,
optionalExtra_tree_right
) VALUES (
inOptionName,
inLeafType,
myRight + 1,
myRight + 2
);
SELECT LAST_INSERT_ID() AS optionalExtraID;
END;
然后使用以下调用调用此函数
CALL addOptionalExtraToTree(0,'New root option','Region');
CALL addOptionalExtraToTree(4,'New child option','Area');
我建议你看看这个 我已经建立了一个几乎相同的数据树,并且使用上面文档中建议的方法使问题变得非常简单,特别是当涉及到确定低至n个水平的父母和兄弟姐妹时 简短的版本是在每个节点的“左”和“右”上分配一个数字,然后使用该数字可以非常有效地选择树的段。那篇文章中有一个更冗长的版本,它的解释比我所能解释的要彻底得多,并且包含了有用的MySQL代码 这是主表的潜在轮廓
treeTable (
// ID field
id INT UNSIGNED PK AI,
// Fields for branching
lft INT UNSIGNED,
rgt INT UNSIGNED,
// ID fields for the specific types
leafType ENUM('Branch','Area','Region'),
leafID INT UNSIGNED,
leafName VARCHAR
)
UNIQUE INDEX (leafType,leafID)
如果您需要每种类型的特定数据,那么您可以为它们创建单独的表,但上面的内容可以让您创建树,映射出id,并允许将关系与显示名称一起存储
当然,每个叶型之间的标准化数据越多越好,理想情况下,它们实际上都是相同类型的数据,因为它们都是地理分区
以您的数据样本为例
Branch 3
Branch 4
Branch 5
Area 6
Region 10
Area 2
您可能最终会得到如下表格:
id lft rgt leafType leafID
1 1 2 'Branch' 3
2 3 4 'Branch' 4
3 5 12 'Branch' 5
4 6 9 'Area' 6
5 7 8 'Region' 10
6 10 11 'Area' 2
有关如何插入etc的查询可在链接文章中找到,即(逐字引用自)
然后一个SELECT可以显示树(同样是源代码中的逐字)
当然,上面2中的字段/表名是不变的,但您可以根据需要更新表/字段名
在我的最新评论之后,下面是用于插入新行的存储过程的定义
CREATE PROCEDURE `addOptionalExtraToTree`(inParentOptionID INT,inOptionName VARCHAR(40),inLeafType VARCHAR(20))
BEGIN
DECLARE myRight INT UNSIGNED DEFAULT 0;
SELECT optionalExtra_tree_right-1
INTO myRight
FROM optionalExtras
WHERE optionalExtraID = inParentOptionID;
IF myRight = 0 THEN
SELECT COALESCE(MAX(optionalExtra_tree_right),0)
INTO myRight
FROM optionalExtras;
END IF;
UPDATE optionalExtras
SET optionalExtra_tree_right = optionalExtra_tree_right + 2
WHERE optionalExtra_tree_right > myRight;
UPDATE optionalExtras
SET optionalExtra_tree_left = optionalExtra_tree_left + 2
WHERE optionalExtra_tree_left > myRight;
INSERT INTO optionalExtras (
optionalExtra_name,
optionalExtra_leaf_type,
optionalExtra_tree_left,
optionalExtra_tree_right
) VALUES (
inOptionName,
inLeafType,
myRight + 1,
myRight + 2
);
SELECT LAST_INSERT_ID() AS optionalExtraID;
END;
然后使用以下调用调用此函数
CALL addOptionalExtraToTree(0,'New root option','Region');
CALL addOptionalExtraToTree(4,'New child option','Area');
根据我的理解,我刚刚读了n,我看到了两个问题:首先,我将数据分布在多个表中,而不是像
类别中的表那样仅分布在一个表中。其次,我有多个父项,比如电子产品,所以不管它们是否有子项,它都会循环通过所有父项。首先,您可以有多个父节点。如果有一个节点的左右比例为1:4,另一个节点的左右比例为5:6,则即使第二个节点没有子节点,SELECT也会返回所有节点。第二点是,您将所有数据视为一棵树,这表明数据类型相似,因此,为了能够有效地做到这一点,可能需要对关键区域进行重组,使其正常化,将在上面添加一个建议的表布局。因此,基本上你是在要求我创建另一个表,该表具有我的分支/区域/区域的超级映射。我还不清楚如何在这个表中插入值。如果你不介意的话,请你从我的问卷中挑选数据,向我解释一下你的表格在我的数据中会是什么样子?谢谢你提供了一个详细的例子。但我怎么知道每次我的左右值是多少呢。由于我正在为应用程序构建此功能,如何为lft
和rgt
插入正确的值?你知道我的意思吗?你可以在存储过程中添加插入逻辑。我只是在我自己的表中这样做了,其中存储过程作为输入(parentID、leafType、leaftname)(我没有单独的leaftid)。如果我将parentID指定为0,它会将其作为新的根节点添加到树的末尾。根据我的理解,我刚刚读取了n,我发现了两个问题:首先,我的数据分布在多个表上,而不是像