基于递归函数的超文本标记语言网站地图

时间:2022-01-18 作者:Daveh0

我正在尝试将我的页面结构呈现为有序列表(<ol>) 使用嵌套的有序列表显示层次结构。所以它应该看起来像

<ol>
  <li>
    About
    <ol>
      <li>
        Leadership
        <ol>
          <li>CEO</li>
          <li>COO</li>
        </ol>
      </li>
    </ol>
  </li>
  <li>Services</li>
  <li>Products</li>
</ol>

or

<关于领导力,我创建了一个函数来获取1级页面,对于任何包含子页面的页面,我都会递归调用该函数。

function aiv_get_sibling_pages($cur_page = null) {
    $front_page_id = get_option(\'page_on_front\');
    $next_page = $cur_page ? $cur_page : get_post($front_page_id);

    $out = \'\';

    $pages_args = array(
        \'exclude\' => \'\', /* ID of pages to be excluded, separated by comma */
        \'post_type\' => \'page\',
        \'post_status\' => \'publish\',
        \'parent\' => $next_page -> post_parent
    );
    $pages = get_pages($pages_args);

    $out .= \'<ol>\';
    foreach($pages as $page) {
        $next_page = $page;

        $out .=  \'<li>\';
        $out .= $page -> post_title;
        $child_pages = get_pages(\'child_of=\' . $page->ID);
        if(count($child_pages) > 0) {
            $out .= aiv_get_sibling_pages($next_page);
        }
        $out .= \'</li>\';   
    }
    $out .= \'</ol>\';

    return $out;
}
在递归部分之前,一切都按预期工作:aiv_get_sibling_pages($next_page);

这会产生错误:

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes) in /home/anupadmin/example.com/wp-includes/post.php on line 5781

我不完全确定这意味着什么,但我猜测,如果我的内存不足,那就是我在做一些效率低下的事情。有谁能告诉我一个更好的方法来做到这一点,或者解释一下为什么我会这样做;我收到错误了吗?

更新下面是一个经过清理的工作版本,它实现了以下公认答案中的解决方案:

function aiv_get_sibling_pages($parent_id = 0) {
    $out = \'\';
    $pages_args = array(
        \'exclude\' => \'\',
        \'post_type\' => \'page\',
        \'post_status\' => \'publish\',
        \'parent\' => $parent_id
    );
    $pages = get_pages($pages_args);    
    if($pages) {
        $extra_className = $parent_id > 0 ? \' child-list\' : \'\';
        $out .= \'<ol class="sitemap__list--ordered \' . $extra_className . \'">\';
        foreach($pages as $page) {
            $out .=  \'<li class="sitemap__item">\';
            $out .= $page -> post_title;
            $out .= aiv_get_sibling_pages($page -> ID);
            $out .= \'</li>\';   
        }
        $out .= \'</ol>\';
    }
    return $out;
}

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

“The”;“内存耗尽”;函数中的此部分导致出现问题错误:\'parent\' => $next_page -> post_parent, 实际上应该是\'parent\' => $next_page -> ID (或者我会省略不必要的空格,即\'parent\' => $next_page->ID).

错误可以这样说明:

$cur_page = get_post( 123 ); // assume the post_parent is 45
aiv_get_sibling_pages( $cur_page );
// 1. get_pages() is called with \'parent\' set to 45.

// 2. Assume get_pages() returned page 123 as the 1st item.
// 3. Your `foreach` calls aiv_get_sibling_pages( <the post object for page 123> )

// 4. .. and then the loop restarts at step 1 and never ends..
// eventually, PHP exits with the "memory exhausted" error :(
如前所述,使用\'parent\' => $next_page->ID 内存错误就会消失。

但我也会做出以下改变:

$out .= \'<ol>\';, 添加以下内容:

// Don\'t add the OL if there are no more pages.
if ( empty( $pages ) ) {
    return \'\';
}
  • get_pages()foreach 没有必要。所以

    // Replace this:
    $child_pages = get_pages(\'child_of=\' . $page->ID);
    if(count($child_pages) > 0) {
        $out .= aiv_get_sibling_pages($next_page);
    }
    
    // with just:
    $out .= aiv_get_sibling_pages( $next_page );
    
    wp_list_pages()..类似这样:

    $list = wp_list_pages( array(
        \'child_of\' => 123, // just change 123 to the correct ID
        \'title_li\' => \'\',
        \'echo\'     => false,
    ) );
    
    echo \'<ol>\' . str_replace(
        [ \'<ul>\', \'<ul \', \'</ul>\' ],
        [ \'<ol>\', \'<ol \', \'</ol>\' ],
        $list
    ) . \'</ol>\';
    
    但是,如果您想完全控制HTML,那么在这种情况下,您的自定义函数会更容易。