WooCommerce重复SKU商品库存同步问题及最优方案咨询
解决WooCommerce重复SKU库存同步问题的最优方案
核心思路
避免无限循环的关键是在触发同步时添加一个标记,跳过后续的钩子触发,防止重复执行同步逻辑。
具体实现步骤
1. 基于woocommerce_product_set_stock钩子实现同步逻辑
在钩子函数里先检查同步标记,若处于同步状态则直接返回;未同步时标记状态,查询所有同SKU商品并批量更新库存,最后取消标记。
2. 基础代码示例
add_action( 'woocommerce_product_set_stock', 'sync_duplicate_sku_stock', 10, 2 ); function sync_duplicate_sku_stock( $product, $stock_quantity ) { // 检查同步标记,避免无限循环 if ( defined( 'IS_SYNCING_DUPLICATE_SKU' ) && IS_SYNCING_DUPLICATE_SKU ) { return; } $sku = $product->get_sku(); if ( empty( $sku ) ) { return; } // 设置同步标记 define( 'IS_SYNCING_DUPLICATE_SKU', true ); // 查询所有同SKU的商品(排除当前商品) $args = array( 'post_type' => 'product', 'posts_per_page' => -1, 'post__not_in' => array( $product->get_id() ), 'meta_query' => array( array( 'key' => '_sku', 'value' => $sku, 'compare' => '=', ), ), ); $duplicate_products = get_posts( $args ); // 逐个更新库存 foreach ( $duplicate_products as $dup_post ) { $dup_product = wc_get_product( $dup_post->ID ); if ( $dup_product && $dup_product->managing_stock() ) { $dup_product->set_stock_quantity( $stock_quantity ); $dup_product->save(); } } // 取消同步标记 define( 'IS_SYNCING_DUPLICATE_SKU', false ); }
3. 高效优化方案(适合大量同SKU商品)
如果同SKU商品数量较多,直接操作数据库批量更新比逐个调用save()更高效:
add_action( 'woocommerce_product_set_stock', 'sync_duplicate_sku_stock_fast', 10, 2 ); function sync_duplicate_sku_stock_fast( $product, $stock_quantity ) { if ( defined( 'IS_SYNCING_DUPLICATE_SKU' ) && IS_SYNCING_DUPLICATE_SKU ) { return; } $sku = $product->get_sku(); $product_id = $product->get_id(); if ( empty( $sku ) ) { return; } define( 'IS_SYNCING_DUPLICATE_SKU', true ); global $wpdb; // 批量更新_stock字段 $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = %d WHERE meta_key = '_stock' AND post_id IN ( SELECT ID FROM {$wpdb->posts} WHERE post_type = 'product' AND ID != %d AND EXISTS ( SELECT 1 FROM {$wpdb->postmeta} pm WHERE pm.post_id = {$wpdb->posts}.ID AND pm.meta_key = '_sku' AND pm.meta_value = %s ) )", $stock_quantity, $product_id, $sku ) ); // 同步更新_stock_status字段 $stock_status = $stock_quantity > 0 ? 'instock' : 'outofstock'; $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE meta_key = '_stock_status' AND post_id IN ( SELECT ID FROM {$wpdb->posts} WHERE post_type = 'product' AND ID != %d AND EXISTS ( SELECT 1 FROM {$wpdb->postmeta} pm WHERE pm.post_id = {$wpdb->posts}.ID AND pm.meta_key = '_sku' AND pm.meta_value = %s ) )", $stock_status, $product_id, $sku ) ); // 清除商品缓存,确保前端显示最新库存 $duplicate_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'product' AND ID != %d AND EXISTS ( SELECT 1 FROM {$wpdb->postmeta} pm WHERE pm.post_id = {$wpdb->posts}.ID AND pm.meta_key = '_sku' AND pm.meta_value = %s )", $product_id, $sku ) ); foreach ( $duplicate_ids as $id ) { wc_delete_product_transients( $id ); } define( 'IS_SYNCING_DUPLICATE_SKU', false ); }
方案防循环原理
通过全局常量IS_SYNCING_DUPLICATE_SKU作为状态标记,第一次触发钩子执行同步时标记为true,后续更新其他同SKU商品时,钩子再次被触发但检测到标记后直接返回,不会重复执行同步逻辑,彻底避免无限循环。
内容的提问来源于stack exchange,提问作者user7692855
相关产品推荐
相关产品推荐

