Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用递归PHP组织mySQL数据_Php_Mysql_Recursion_If Statement_Adjacency List - Fatal编程技术网

使用递归PHP组织mySQL数据

使用递归PHP组织mySQL数据,php,mysql,recursion,if-statement,adjacency-list,Php,Mysql,Recursion,If Statement,Adjacency List,我正在为一位客户创建一份调查问卷,要求将问题分为3个层次。我已经成功地创建了U.I。然而,在过去的3个小时里,我一直在尝试从数据库中提取数据,以确保所有数据都加载到正确的位置。数据库是由客户组织的,因此我无法控制它: id description parentId about 1 Level 1 0 This is the top level or in my case tab1 2 Level 2 0

我正在为一位客户创建一份调查问卷,要求将问题分为3个层次。我已经成功地创建了U.I。然而,在过去的3个小时里,我一直在尝试从数据库中提取数据,以确保所有数据都加载到正确的位置。数据库是由客户组织的,因此我无法控制它:

id    description    parentId    about
1      Level 1        0           This is the top level or in my case tab1
2      Level 2        0           This is the next tab in the top level
3      Level 1a       1           This is the first category under tab1
4      Level 1b       1           This is the next category under tab1
5      Level 1a1      3           This is the content under the first category of tab1
因此,parentId为0的任何内容都是顶级内容,并且将包含parentId为1的第二级内容,依此类推。令人困惑的是,我几乎无法理解这一点,但这就是我被告知要这样做的方式

什么方法是执行此类操作的最佳方法?下面是我用作参考的另一个问题的示例(尽管不起作用)


任何帮助都将不胜感激。干杯

如果您正好有3个级别,那么您可以尝试以下方法:


我在selects中添加了一个
lvl
字段,每个级别都有不同的值。还添加了o1、o2、o3,以便很好地排序嵌套级别,当然您可能还有其他需要。您可以在PHP中处理所有行,例如,将它们拆分为3个数组(每个级别一个数组),或者根据id创建一个查找表,等等。

如果您正好有3个级别,那么您可以尝试以下方法:


我在selects中添加了一个
lvl
字段,每个级别都有不同的值。还添加了o1、o2、o3,以便很好地排序嵌套级别,当然您可能还有其他需要。您可以在PHP中处理所有行,例如将它们拆分为3个数组(每个级别一个数组),或者根据id创建一个查找表,等等。

我也遇到了类似的问题,但经过大量的Google搜索和StackOverflow:-) 我找到了我的答案。。。。 这是我的编码方式

function showComments($parent = 0)
{
$commentQuery = "SELECT * FROM comment WHERE parent = ".mysql_real_escape_string($parentId);
$commentResult = mysql_query($commentQuery)

while ($row = mysql_fetch_array($commentResult))
{
echo '[Table containing comment data]';
showComments($row['commentID']);
}
}

showComments();

我也有同样的问题,但在谷歌搜索和堆垛泛滥之后:-) 我找到了我的答案。。。。 这是我的编码方式

function showComments($parent = 0)
{
$commentQuery = "SELECT * FROM comment WHERE parent = ".mysql_real_escape_string($parentId);
$commentResult = mysql_query($commentQuery)

while ($row = mysql_fetch_array($commentResult))
{
echo '[Table containing comment data]';
showComments($row['commentID']);
}
}

showComments();

如果您使用的是外部数据库,那么在PHP中这样做可能是值得的,而不是SQL。我还没有对以下内容进行基准测试,所以请尝试使用您的数据,看看性能是否有问题

您可以自己选择如何处理孤立记录(这些记录引用了不再存在的ParentID)

像这样在PHP中排序需要事先准备好所有数据,因此请使用类似PDO的
fetchAll(PDO::FETCH_ASSOC)
方法,其结果如下:

$data_from_database = array(
    array("id" => 1, "parentId" => 0, "description" => "Level 1"),
    array("id" => 2, "parentId" => 1, "description" => "Level 1a"),
    array("id" => 3, "parentId" => 1, "description" => "Level 1b"),
    array("id" => 4, "parentId" => 0, "description" => "Level 2"),
    array("id" => 5, "parentId" => 2, "description" => "Level 1a1"),
    array("id" => 6, "parentId" => 5, "description" => "Level 1a11a"),
    array("id" => 7, "parentId" => 5, "description" => "Level 1a11b"),
    array("id" => 8, "parentId" => 9, "description" => "Level 3"),
);
$data_from_database = array(
    1 => array("id" => 1, "parentId" => 0, "description" => "Level 1", 
               "children" => array(), "is_orphan" => false),
    ...
 );
首先,您需要将主键(ID)作为数组的键。下面还将键“children”和“is_orphan”添加到每个记录中

$data_by_id = array();
foreach($data_from_database as $row)
    $data_by_id[$row["id"]] = $row + array(
        "children" => array(), 
        "is_orphan" => false
    );
这将看起来像这样:

$data_from_database = array(
    array("id" => 1, "parentId" => 0, "description" => "Level 1"),
    array("id" => 2, "parentId" => 1, "description" => "Level 1a"),
    array("id" => 3, "parentId" => 1, "description" => "Level 1b"),
    array("id" => 4, "parentId" => 0, "description" => "Level 2"),
    array("id" => 5, "parentId" => 2, "description" => "Level 1a1"),
    array("id" => 6, "parentId" => 5, "description" => "Level 1a11a"),
    array("id" => 7, "parentId" => 5, "description" => "Level 1a11b"),
    array("id" => 8, "parentId" => 9, "description" => "Level 3"),
);
$data_from_database = array(
    1 => array("id" => 1, "parentId" => 0, "description" => "Level 1", 
               "children" => array(), "is_orphan" => false),
    ...
 );
现在,它变得很棘手:我们将在数组中循环并添加引用

foreach($data_by_id as &$row)
{
    if($row["parentId"] > 0)
    {
        if(isset($data_by_id[$row["parentId"]]))
            $data_by_id[$row["parentId"]]["children"][] = &$row;
        else
            $row["is_orphan"] = true;
    }
}
unset($row); // Clear reference (important).
最后一步是清理数组的“根”。它将包含对重复行的引用

foreach($data_by_id as $id => $row)
{
    // If you use this option, you'll remove
    // orphaned records.
    #if($row["parentId"] > 0)
    #    unset($data_by_id[$id]);

    // Use this to keep orphans:
    if($row["parentId"] > 0 AND !$row["is_orphan"])
        unset($data_by_id[$id]);
}
在每个步骤后使用
print\r($data\u by\u id)
查看发生了什么


如果这证明是一个耗时的操作,请尝试仅通过执行
选择id,parentId FROM…
然后稍后获取元数据(如
说明
)来构建树。您还可以将结果存储在Memcache中或序列化到数据库中

如果您使用的是外部数据库,那么在PHP中这样做可能是值得的,而不是SQL。我还没有对以下内容进行基准测试,所以请尝试使用您的数据,看看性能是否有问题

您可以自己选择如何处理孤立记录(这些记录引用了不再存在的ParentID)

像这样在PHP中排序需要事先准备好所有数据,因此请使用类似PDO的
fetchAll(PDO::FETCH_ASSOC)
方法,其结果如下:

$data_from_database = array(
    array("id" => 1, "parentId" => 0, "description" => "Level 1"),
    array("id" => 2, "parentId" => 1, "description" => "Level 1a"),
    array("id" => 3, "parentId" => 1, "description" => "Level 1b"),
    array("id" => 4, "parentId" => 0, "description" => "Level 2"),
    array("id" => 5, "parentId" => 2, "description" => "Level 1a1"),
    array("id" => 6, "parentId" => 5, "description" => "Level 1a11a"),
    array("id" => 7, "parentId" => 5, "description" => "Level 1a11b"),
    array("id" => 8, "parentId" => 9, "description" => "Level 3"),
);
$data_from_database = array(
    1 => array("id" => 1, "parentId" => 0, "description" => "Level 1", 
               "children" => array(), "is_orphan" => false),
    ...
 );
首先,您需要将主键(ID)作为数组的键。下面还将键“children”和“is_orphan”添加到每个记录中

$data_by_id = array();
foreach($data_from_database as $row)
    $data_by_id[$row["id"]] = $row + array(
        "children" => array(), 
        "is_orphan" => false
    );
这将看起来像这样:

$data_from_database = array(
    array("id" => 1, "parentId" => 0, "description" => "Level 1"),
    array("id" => 2, "parentId" => 1, "description" => "Level 1a"),
    array("id" => 3, "parentId" => 1, "description" => "Level 1b"),
    array("id" => 4, "parentId" => 0, "description" => "Level 2"),
    array("id" => 5, "parentId" => 2, "description" => "Level 1a1"),
    array("id" => 6, "parentId" => 5, "description" => "Level 1a11a"),
    array("id" => 7, "parentId" => 5, "description" => "Level 1a11b"),
    array("id" => 8, "parentId" => 9, "description" => "Level 3"),
);
$data_from_database = array(
    1 => array("id" => 1, "parentId" => 0, "description" => "Level 1", 
               "children" => array(), "is_orphan" => false),
    ...
 );
现在,它变得很棘手:我们将在数组中循环并添加引用

foreach($data_by_id as &$row)
{
    if($row["parentId"] > 0)
    {
        if(isset($data_by_id[$row["parentId"]]))
            $data_by_id[$row["parentId"]]["children"][] = &$row;
        else
            $row["is_orphan"] = true;
    }
}
unset($row); // Clear reference (important).
最后一步是清理数组的“根”。它将包含对重复行的引用

foreach($data_by_id as $id => $row)
{
    // If you use this option, you'll remove
    // orphaned records.
    #if($row["parentId"] > 0)
    #    unset($data_by_id[$id]);

    // Use this to keep orphans:
    if($row["parentId"] > 0 AND !$row["is_orphan"])
        unset($data_by_id[$id]);
}
在每个步骤后使用
print\r($data\u by\u id)
查看发生了什么


如果这证明是一个耗时的操作,请尝试仅通过执行
选择id,parentId FROM…
然后稍后获取元数据(如
说明
)来构建树。您还可以将结果存储在Memcache中或序列化到数据库中

对不起,如果这是一个无知的问题。但是我该如何用php组织它呢?biziclop的想法很好。你有三个层次。使用查询获取所有记录,然后对它们运行循环,检查
parentId
并分配给数组。我想没有别的办法了。好的,有-使用一个查询来获取顶级记录,然后循环并为每个顶级记录找到它的子记录,然后为每个子记录您将需要一个查询来找到它的子记录,等等。问题是我无法控制数据库。所以一切都必须通过php来完成。我做了一些查找,递归php树遍历似乎是实现这一点的方法。尽管o.o什么都不起作用。除了我的答案中的查询返回的字段之外,您还需要处理哪些数据?更新了我的问题,以进一步反映我的理解,并使我的观点更加清晰(如果这是一个无知的问题)。但是我该如何用php组织它呢?biziclop的想法很好。你有三个层次。使用查询获取所有记录,然后对它们运行循环,检查
parentId
并分配给数组。我想没有别的办法了。好的,有-使用一个查询来获取顶级记录,然后循环并为每个顶级记录找到它的子记录,然后为每个子记录您将需要一个查询来找到它的子记录,等等。问题是我无法控制数据库。所以一切都必须通过php来完成。我做了一些查找,递归php树遍历似乎是我要做的事情