WordPress热门文章循环调用自定义分类法时去除重复值方案
问题根源
你写的去重逻辑不生效,核心是作用域错了:array_unique()写在单篇文章的遍历循环内部,只对当前这篇文章关联的分类ID生效,跨文章的重复分类ID从来没被归集到同一个数组里处理,自然没法过滤重复项。
另外你原代码里还有两个逻辑问题:
$term->term_id本身是单个整数,不是逗号分隔的字符串,对它做explode、implode完全是无效操作- 热门文章查询的排序参数写的是
ASC(升序),实际会取到浏览量最低的内容,属于笔误,热门内容应该用DESC(降序)
修复方案
核心思路:提前定义一个全局数组记录已经输出过的分类ID,遍历文章拿到分类ID时先做判断,已经在记录数组里的直接跳过,没记录的才输出并存入数组,从根源避免重复。
这种方式比先收集所有ID再统一去重二次遍历的性能更好,不需要额外跑循环。
修正后完整代码
<?php $popular = array( 'post_type' => 'videos', 'posts_per_page' => 8, 'meta_key' => 'post_views_count', 'orderby' => 'meta_value_num', 'order' => 'DESC', // 修正原排序笔误:按浏览量从高到低取内容 'offset' => 1, ); $popular_loop = new WP_Query( $popular ); // 初始化去重标记数组,存已经输出过的分类ID $processed_terms = array(); if( $popular_loop->have_posts() ){ while( $popular_loop->have_posts() ) : $popular_loop->the_post(); $terms = get_the_terms( get_the_ID(), 'seasons' ); // 跳过无分类、查询报错的情况 if( empty($terms) || is_wp_error($terms) ) continue; foreach($terms as $term) { // 统一取目标分类:有父级取父分类ID,无父级取当前分类ID $target_term_id = $term->parent ? $term->parent : $term->term_id; // 该分类已经输出过,直接跳过 if( in_array($target_term_id, $processed_terms) ) continue; // 标记为已处理 $processed_terms[] = $target_term_id; // 获取分类完整对象,后续所有字段都从这里取 $target_term = get_term( $target_term_id, 'seasons' ); if( is_wp_error($target_term) ) continue; // 按需输出你需要的分类信息即可 $term_name = $target_term->name; $term_link = get_term_link( $target_term ); // 如果有分类封面类的自定义term meta,直接在这里读取,示例: // $term_cover = get_term_meta( $target_term_id, 'season_cover', true ); ?> <div class="hot-season-card"> <p>分类ID:<?php echo esc_html($target_term_id); ?></p> <h3><?php echo esc_html($term_name); ?></h3> <a href="<?php echo esc_url($term_link); ?>">查看该季全部内容</a> </div> <?php } endwhile; wp_reset_postdata(); } ?>
额外优化提示
- 如果需要限制最终输出的不重复分类数量,比如只展示6个热门分类,可以加个计数变量,输出达到数量后直接break所有循环即可,不用遍历完所有8篇文章
- 输出分类字段时记得用
esc_html()、esc_url()做转义,避免安全问题 - 文章浏览量统计函数记得放在文章详情页的对应位置调用,不要在列表页触发,否则统计数据不准
内容的提问来源于stack exchange,提问作者IamLearningPHP
相关产品推荐
相关产品推荐

