WooCommerce按浏览量实现产品热门排序失效问题排查
WooCommerce按浏览量排序商品不生效修复方案
原有代码失效的核心原因:
- 过滤器未设置足够高的执行优先级:
woocommerce_get_catalog_ordering_args默认优先级为10,WooCommerce核心的原生popularity排序逻辑、主题或其他电商插件的同钩子逻辑优先级更高,会直接覆盖你定义的排序参数,最终回退到默认的按发布日期排序规则。 - 直接复用原生
popularity排序标识存在冲突:WooCommerce原生popularity排序默认绑定商品销量逻辑,部分版本核心代码会在查询执行前重置该标识对应的排序参数,导致自定义修改不生效。
可直接落地的修复代码
1. 新增独立的浏览量排序选项
不要占用原生popularity标识,新增独立排序项避免逻辑冲突:
// 将按浏览量排序加入商品列表排序选项 add_filter( 'woocommerce_catalog_orderby', 'add_custom_views_sort_option' ); function add_custom_views_sort_option( $sort_options ) { $sort_options['views_desc'] = '按浏览量从高到低'; return $sort_options; }
2. 绑定排序查询参数(设置最高优先级避免被覆盖)
// 为自定义浏览量排序绑定查询参数,优先级设为999保证最后执行不被覆盖 add_filter( 'woocommerce_get_catalog_ordering_args', 'set_views_sort_args', 999 ); function set_views_sort_args( $args ) { $current_orderby = isset( $_GET['orderby'] ) ? wc_clean( wp_unslash( $_GET['orderby'] ) ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) ); if ( 'views_desc' === $current_orderby ) { $args['orderby'] = 'meta_value_num'; $args['order'] = 'DESC'; $args['meta_key'] = '_total_views_count'; $args['meta_type'] = 'NUMERIC'; // 兼容无浏览量的商品,避免商品被隐藏 $args['meta_query'] = [ 'relation' => 'OR', [ 'key' => '_total_views_count', 'compare' => 'EXISTS', ], [ 'key' => '_total_views_count', 'compare' => 'NOT EXISTS', ] ]; } return $args; }
3. (可选)优化浏览量计数逻辑
原计数逻辑存在取数不准、爬虫误计数问题,可替换为更稳定的版本:
// 优化后的商品浏览量计数 add_action( 'template_redirect', 'optimized_product_view_counter' ); function optimized_product_view_counter() { // 排除后台访问、非商品页、爬虫访问 if ( is_admin() || ! is_product() || ( isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/bot|crawl|spider/i', $_SERVER['HTTP_USER_AGENT']) ) ) { return; } global $post; $current_views = (int)get_post_meta( $post->ID, '_total_views_count', true ); update_post_meta( $post->ID, '_total_views_count', $current_views + 1 ); }
生效注意事项
- 代码添加后如果要将浏览量排序设为默认,直接进入WooCommerce后台「产品-显示-默认商品排序」,选择刚新增的「按浏览量从高到低」即可,无需额外代码。
- 如果部署后仍不生效,先清空网站缓存、WooCommerce商品瞬态缓存,部分缓存插件会存储商品列表的旧查询结果,缓存未清理时新逻辑不会触发。
内容的提问来源于stack exchange,提问作者Qamar Ul Din Hamza
相关产品推荐
相关产品推荐

