【问题标题】:Replacing WordPress' wp_list_pages function with a multidimensional array to reduce response time用多维数组替换 WordPress 的 wp_list_pages 函数以减少响应时间
【发布时间】:2013-02-28 20:47:34
【问题描述】:

在没有所有可能的参数和东西的情况下,我正在尝试构建一个比 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 毫秒。太棒了!

【问题讨论】:

  • 使用递归根据父id创建层次结构..见树遍历en.m.wikipedia.org/wiki/Tree_traversal#section_2
  • 没错,这就是我想要的。你有任何示例代码吗?一直在尝试将子数组 array_push 给他们的父母,但我做错了。

标签: wordpress multidimensional-array query-optimization response-time


【解决方案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);

【讨论】:

  • 太好了,我最终在我的层次结构中有四个级别,但对这段代码稍作修改,我就让它工作了。谢谢!
【解决方案2】:

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

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

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

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

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

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

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

【讨论】:

  • 好的,有趣。我最终使用了 4 级层次结构,所以@Gedrox 的解决方案(几乎)对我来说已经足够了。谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-04-15
  • 2017-10-20
  • 2022-09-23
  • 2015-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多