You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce产品评论汇总栏问题:无法按单个产品统计

Fixing Single Product Review Summary & Refining Your Code

Looks like you're trying to build a WooCommerce product review summary bar, and you're two steps away from getting it perfect! Let's tackle both your issues one by one:

1. The Root Cause of "All Products" Review Count

Your current functions aren't properly targeting the single product ID consistently:

  • In get_review_star_count(), you're using an undefined $product_id variable (it's not passed into the function, so PHP can't resolve it).
  • In get_total_review_star_count(), you're relying on the global $post->ID, which might not always point to the current product in all contexts (like if you're using this in a template part or custom shortcode).

2. Professional Code Refinements & Fixes

We'll rebuild this using WooCommerce's native functions where possible (they're optimized and handle edge cases), add proper parameter passing, cache results to reduce database calls, and clean up the structure for maintainability.

Revised Complete Code

/**
 * Get total number of approved reviews for a specific product
 * @param int $product_id ID of the target product
 * @return int Total reviews count
 */
function get_product_total_reviews( $product_id ) {
    // Use WooCommerce's built-in function for accurate review count
    $product = wc_get_product( $product_id );
    if ( ! $product ) return 0;
    
    return $product->get_review_count();
}

/**
 * Get number of reviews with a specific star rating for a product
 * @param int $product_id ID of the target product
 * @param int $rating Star rating (1-5)
 * @return int Count of reviews with this rating
 */
function get_product_rating_count( $product_id, $rating ) {
    // Validate input to avoid invalid queries
    if ( ! is_numeric( $rating ) || $rating < 1 || $rating > 5 ) return 0;
    
    // Cache results to avoid repeated database calls in the loop
    static $rating_counts = [];
    $cache_key = $product_id . '_' . $rating;
    
    if ( isset( $rating_counts[$cache_key] ) ) {
        return $rating_counts[$cache_key];
    }
    
    $count = get_comments([
        'post_id'      => $product_id,
        'status'       => 'approve',
        'post_status'  => 'publish',
        'post_type'    => 'product',
        'meta_key'     => 'rating',
        'meta_value'   => $rating,
        'count'        => true,
        'no_found_rows' => true, // Optimize query by skipping unnecessary row count
    ]);
    
    $rating_counts[$cache_key] = $count;
    return $count;
}

// Display the review summary bar
function display_product_review_summary( $product_id = null ) {
    // Fallback to current product ID if no ID is provided
    if ( is_null( $product_id ) ) {
        global $post;
        $product_id = $post->ID;
    }
    
    $total_reviews = get_product_total_reviews( $product_id );
    if ( $total_reviews === 0 ) {
        echo '<div class="reviews_bar uk-margin-medium"><p>No reviews yet.</p></div>';
        return;
    }
    ?>
    <div class="reviews_bar uk-margin-medium">
        <h5><?php esc_html_e( 'Review summary:', 'text-domain' ); ?></h5>
        <?php for ( $i = 5; $i >= 1; $i-- ) : ?>
            <?php
            $rating_count = get_product_rating_count( $product_id, $i );
            $percentage = floor( ( $rating_count / $total_reviews ) * 100 );
            ?>
            <div class="bars">
                <div class="star_num" data-uk-leader>
                    <?php printf( _n( '%s star', '%s stars', $i, 'text-domain' ), $i ); ?>
                </div>
                <div class="star_perc" style="width: <?php echo esc_attr( $percentage . '%' ); ?>">
                    <?php echo esc_html( $rating_count . ' / ' . $percentage . '%' ); ?>
                </div>
            </div>
        <?php endfor; ?>
    </div>
    <?php
}

// Usage: Call this function in your product template
// display_product_review_summary(); // Uses current product ID
// OR pass a specific product ID: display_product_review_summary( 123 );

Key Improvements Explained

  • Single Product Targeting: Every function accepts a $product_id parameter, ensuring we always query reviews for the exact product you want. We only fall back to the global $post when no ID is explicitly provided.
  • WooCommerce Native Functions: wc_get_product() and get_review_count() are maintained by WooCommerce, so they handle edge cases (like product variations, hidden products) better than custom get_comments() calls.
  • Query Optimization: Added no_found_rows to speed up comment queries, and used static caching to avoid running the same rating count query multiple times in the loop.
  • Security: Used esc_html() and esc_attr() to sanitize output, preventing potential XSS vulnerabilities.
  • Clean Structure: Split logic into reusable functions, making the code easier to maintain, test, and modify later.
  • Edge Case Handling: Added a check for zero reviews to show a friendly message instead of empty bars.

Final Notes

  • Replace text-domain with your theme/plugin's actual text domain for proper translation support.
  • Move the inline style="width: ..." to your CSS file for better separation of concerns (e.g., add a class like star-percentage and set width via CSS, using inline styles only for dynamic percentage values).

内容的提问来源于stack exchange,提问作者Oussama Bouyardane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:04:19