在WooCommerce首页显示总顾客评论数及全局平均评分问题求助
解决WooCommerce首页展示全局评论总数和平均评分的问题
咱们先搞定评论总数显示错误的问题,再解决全局平均评分的需求。
一、修复全局评论总数显示错误
你原来的代码里用了get_comment_count($comments),这个函数的参数是单个文章ID,不是评论对象数组,所以它返回的是当前页面(首页)的评论数,才会出现实际4条评论却显示1的情况。
正确的做法是利用WP_Comment_Query的found_comments属性,它会返回符合查询条件的总评论数(不受分页影响):
<?php // 配置查询参数:仅获取已通过的产品评论 $args = array( 'status' => 'approve', 'post_status' => 'publish', 'post_type' => 'product', 'no_found_rows' => false, // 必须设为false才能让查询返回总评论数 ); $comments_query = new WP_Comment_Query; $comments_query->query($args); // 获取总评论数 $total_reviews = $comments_query->found_comments; ?> <span class="total_reviews"><?php echo esc_html($total_reviews) . ' reviews'; ?></span>
二、实现全局平均评分
单个产品的平均评分是存在产品的元数据里的,要计算全局平均,需要把所有产品的「评分×评论数」求和,再除以总评论数(这样才是加权平均,更准确)。这里提供两种方法:
方法1:使用WP_Query(更符合WordPress规范)
<?php // 查询所有有评论的已发布产品 $products_args = array( 'post_type' => 'product', 'post_status' => 'publish', 'meta_query' => array( array( 'key' => '_wc_review_count', 'value' => 0, 'compare' => '>', 'type' => 'numeric' ) ), 'fields' => 'ids', // 只获取产品ID,提升查询效率 'posts_per_page' => -1 // 获取所有符合条件的产品 ); $products_query = new WP_Query($products_args); $total_rating_sum = 0; $total_reviews_count = 0; if ($products_query->have_posts()) { foreach ($products_query->posts as $product_id) { // 获取产品的平均评分和评论数 $product_avg_rating = (float)get_post_meta($product_id, '_wc_average_rating', true); $product_review_count = (int)get_post_meta($product_id, '_wc_review_count', true); if ($product_avg_rating && $product_review_count) { // 累加加权评分总和和总评论数 $total_rating_sum += $product_avg_rating * $product_review_count; $total_reviews_count += $product_review_count; } } wp_reset_postdata(); // 重置查询状态 } // 计算全局平均评分(保留1位小数) $global_avg_rating = 0; if ($total_reviews_count > 0) { $global_avg_rating = round($total_rating_sum / $total_reviews_count, 1); } ?> <span class="global-average-rating"><?php echo esc_html($global_avg_rating); ?>/5</span>
方法2:直接SQL查询(效率更高,适合产品较多的站点)
如果你的站点产品数量很多,直接用SQL查询会比WP_Query更快:
<?php global $wpdb; // 从数据库直接计算加权总评分和总评论数 $rating_data = $wpdb->get_row(" SELECT SUM(pm.meta_value * (SELECT meta_value FROM $wpdb->postmeta WHERE post_id = p.ID AND meta_key = '_wc_review_count')) AS total_weighted_rating, SUM((SELECT meta_value FROM $wpdb->postmeta WHERE post_id = p.ID AND meta_key = '_wc_review_count')) AS total_reviews FROM $wpdb->posts p LEFT JOIN $wpdb->postmeta pm ON p.ID = pm.post_id WHERE p.post_type = 'product' AND p.post_status = 'publish' AND pm.meta_key = '_wc_average_rating' AND pm.meta_value > 0 "); $global_avg_rating = 0; if ($rating_data->total_reviews > 0) { $global_avg_rating = round($rating_data->total_weighted_rating / $rating_data->total_reviews, 1); } ?> <span class="global-average-rating"><?php echo esc_html($global_avg_rating); ?>/5</span>
内容的提问来源于stack exchange,提问作者Oussama Bouyardane
相关产品推荐
相关产品推荐

