获取WooCommerce所有产品ID数组并实现每日随机4个产品折扣的函数异常排查求助
解决你的WooCommerce每日随机折扣产品问题
我来帮你排查并修复这个函数的问题,主要有几个关键错误需要修正:
1. array_rand 使用错误
你当前用array_rand($ids, 4)获取的是数组的索引键名,而不是产品ID本身。比如如果$ids是[10,20,30,40,...],array_rand返回的会是类似[0,2,5,7]这样的索引,导致in_array($product->get_id(), $discounted_products)永远匹配失败。
正确的做法是通过索引提取对应的ID值:
$discounted_products = array_intersect_key($ids, array_flip(array_rand($ids, 4)));
2. 缺少每日随机的持久化逻辑
当前代码每次调用函数都会重新生成随机产品,用户刷新页面就会变,不符合“每日固定4个”的需求。我们可以用WordPress的transient缓存来存储每日的随机ID,设置24小时过期。
3. wc_get_products 参数优化
虽然return => 'ids'和limit => -1是正确的,但建议明确添加status => 'publish'确保只获取已发布的产品,避免拿到草稿或私密产品。
4. 函数未挂载到正确的钩子
你的函数定义了,但如果没有挂载到WooCommerce的价格过滤钩子上,根本不会被执行。需要添加钩子挂载代码。
修正后的完整代码
function periodic_discount_prices( $price, $product ){ // 尝试从transient获取今日折扣产品ID $discounted_products = get_transient('daily_discounted_product_ids'); // 如果transient不存在(当日首次执行),重新生成并缓存 if ( false === $discounted_products ) { // 获取所有已发布的产品ID $ids = wc_get_products( array( 'return' => 'ids', 'limit' => -1, 'status' => 'publish' ) ); // 确保产品数量≥4才随机选4个,避免报错 if ( count($ids) >= 4 ) { $discounted_products = array_intersect_key($ids, array_flip(array_rand($ids, 4))); } else { // 如果产品不足4个,就全部设置折扣(可选逻辑,可根据需求修改) $discounted_products = $ids; } // 缓存24小时(86400秒) set_transient('daily_discounted_product_ids', $discounted_products, 86400); } // 检查是否启用折扣,且当前产品在折扣列表中 if( get_discount_period_rate() && in_array( $product->get_id(), $discounted_products ) ){ $price = $product->get_regular_price() * get_discount_period_rate(); } return $price; } // 挂载到WooCommerce价格获取钩子 add_filter('woocommerce_product_get_price', 'periodic_discount_prices', 10, 2); add_filter('woocommerce_product_variation_get_price', 'periodic_discount_prices', 10, 2); // 如果需要支持变体产品
关键修改点解释:
- Transient缓存:确保每日只生成一次随机产品,用户访问时不会频繁变动。
- array_rand修正:通过
array_flip和array_intersect_key获取真正的产品ID值。 - 钩子挂载:添加了
woocommerce_product_get_price和变体的钩子,让函数能被WooCommerce调用。 - 边界处理:增加了产品数量不足4个的判断,避免
array_rand抛出错误。
内容的提问来源于stack exchange,提问作者Luc Mosser
相关产品推荐
相关产品推荐

