0

我试图在没有所有可能的参数和东西的情况下,拼凑一个比 WordPress 的 wp_list_pages 更有效(更少的数据库调用等)的函数。wp_posts 表如下所示:

ID      post_title          post_parent
1       Skate brand no1     5
2       Skate brand no2     5
3       Products            0
4       Bikes               3
5       Skateboards         3
6       About               0
7       Contact             6
8       Surfboards          3

我想要一个看起来像这样的数组:

array
    1 => Products
        array
            1 => Bikes
            2 => Skateboards
                array
                    1 => Skate brand no1
                    2 => Skate brand no2
            3 => Surfboards
    2 => About
        array
            1 => Contact

我应该如何处理这项任务?

更新!

通过用@Gedrox 提供的代码替换我网站首页上的大约 4 或 5 个 wp_list_pages,每日平均响应时间从不稳定的 780-1000 毫秒下降到稳定的 595-625 毫秒。惊人的!

4

2 回答 2

1

如果您需要完整的站点地图,您应该阅读所有记录(SELECT我假设是一条)并在 PHP 代码中按层次组织。

示例代码:

// TODO: get this from DB
$list = array(
    array('ID' => 1, 'post_title' => 'Skate brand no1', 'post_parent' => 5),
    array('ID' => 2, 'post_title' => 'Skate brand no2', 'post_parent' => 5),
    array('ID' => 3, 'post_title' => 'Products', 'post_parent' => 0),
    array('ID' => 4, 'post_title' => 'Bikes', 'post_parent' => 3),
    array('ID' => 5, 'post_title' => 'Skateboards', 'post_parent' => 3),
    array('ID' => 6, 'post_title' => 'About', 'post_parent' => 0),
    array('ID' => 7, 'post_title' => 'Contact', 'post_parent' => 6),
    array('ID' => 8, 'post_title' => 'Surfboards', 'post_parent' => 3),
);

$rootPages = array();
$pagesById = array();

foreach ($list as $key => &$row) {
    if ($row['post_parent'] == 0) {
        $rootPages[] = &$row;
    }
}

foreach ($list as $key => &$row) {
    $pagesById[$row['ID']] = &$row;
}

foreach ($list as $key => &$row) {
    if ($row['post_parent'] != 0) {
        $pagesById[$row['post_parent']]['children'][] = &$row;
    }
}

print_r($rootPages);
于 2013-02-28T20:51:00.607 回答
1

据我所知,在您的示例中,您正在考虑您可以拥有任意数量的孩子。

这种方法必须通过使用递归来完成。事实上,在 wordpress 的结构中,如果不进行与节点数量一样多的查询来检查节点是否有子节点,就无法获得整个树。

这是一个树状结构,允许您n为每个节点创建子节点。目前,MySQL 不支持递归子查询,因此该表逻辑不允许您在不需要log(m)查询的情况下检索完整的“路径”(平均情况,m您考虑的树的节点数量在哪里)。

这并不像看起来那么简单。有一些方法可以在一个查询中检索所有树,并且通过这种方式将 sql 查询最小化为一个,但这需要您修改数据表。

这是一个包含示例的更详细的站点,您可以在其中看到一些您可以做的替代方案。

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

编辑: 我重复:这不是你可以通过 1 个 mysql 查询而没有递归得到的东西。请不要误解无限孩子的概念。在@Gedrox 的回答中,只有在树中有3 个级别时它才会起作用。

于 2013-02-28T21:02:33.247 回答