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

WooCommerce get_available_variations获取Any规则全变体问题

问题说明

WooCommerce开发中调用get_available_variations()函数时,会遇到设置了ANY(匹配所有属性值)变体的可变商品返回结果不全的问题:

  • 测试可变商品为socks(袜子),仅配置1个属性size(尺寸),关联X、M、XL三个属性值
  • 该商品仅创建1个设置为ANY规则的变体,未给三个尺寸单独创建独立变体

函数返回结果结构如下:

array(1) {
  [0]=>
  array(25) {
    ["attributes"]=>
    array(1) {
      ["attribute_pa_size"]=>
      string(0) ""
    }
    ...
  }
}

该返回逻辑本身符合WooCommerce后台规则:ANY选项对应的存储值为空字符串,商品前台详情页也能正常展示3个可选尺寸;其他为每个属性值单独创建变体的可变商品,调用该函数都能正常返回完整变体列表。

原有商品导出代码如下,需要适配上述场景生成完整的3个有效变体条目:

$products = wc_get_products(array(
    'status' => 'publish',
    'limit' => -1,
));

if ($products) {
    echo '<products>';
    foreach ($products as $product) {
        echo '<product>';
        echo '<id>'. $product->get_id() .'</id>';
        echo '<title>'. esc_html(strip_tags($product->get_title())) .'</title>';
        echo '<description>'. esc_html(str_replace('&nbsp;', ' ', $product->get_short_description())) .'</description>';
        echo '<price>'. $product->get_sale_price() .'</price>';
        echo '<old_price>'. $product->get_regular_price() .'</old_price>';
        echo '<sku>'. esc_html($product->get_sku()) .'</sku>';
            
        if ($product->get_type() == 'variable') {
            $product_variations = $product->get_available_variations();
            
            echo '<options>';
            
            foreach ($product_variations as $variation) {
                echo "<option>
                    {";
                    foreach ($variation['attributes'] as $key=>$value) {
                        $taxonomy = str_replace('attribute_', '', $key);
                        $term = get_term_by('slug', $value, $taxonomy);
                        echo "
                        'label' : '". wc_attribute_label($taxonomy) ."',
                        'value' : '". $term->name ."',
                        ";
                    }
                echo "
                    'sku' : '". $variation['sku'] ."',
                    'weight' : '". (!empty($variation['weight']) ? $variation['weight'] : 0) ."',
                    'quantity' : ". ($variation['is_purchasable'] === true ? 10 : 0) .",
                    'image' : '". $variation['image']['url'] ."',
                    'price' : ". $variation['display_regular_price'] .",
                    'discounted_price' : ". $variation['display_price'] ."
                    }
                </option>
                ";
            }
            
            echo '</options>';
        }
        echo '</product>';
    }
    echo '</products>';
}
解决方案

核心处理逻辑:识别变体中属性值为空(即设置为ANY匹配所有值)的条目,遍历对应属性的所有可选值,通过笛卡尔积手动展开生成对应数量的变体条目即可。
替换原有可变商品的变体处理部分代码:

if ($product->get_type() == 'variable') {
    $raw_variations = $product->get_available_variations();
    $expanded_variations = [];

    foreach ($raw_variations as $variation) {
        // 区分当前变体内设置为ANY的属性、固定值属性
        $any_attributes = [];
        $fixed_attributes = [];
        foreach ($variation['attributes'] as $attr_key => $attr_value) {
            if ($attr_value === '') {
                $taxonomy = str_replace('attribute_', '', $attr_key);
                // 获取该属性下关联到当前商品的所有可选值
                $any_attributes[$attr_key] = wc_get_product_terms($product->get_id(), $taxonomy, array('fields' => 'slugs'));
            } else {
                $fixed_attributes[$attr_key] = $attr_value;
            }
        }

        // 无ANY规则的普通变体直接加入结果集
        if (empty($any_attributes)) {
            $expanded_variations[] = $variation;
            continue;
        }

        // 计算属性组合笛卡尔积
        $combinations = [[]];
        foreach ($any_attributes as $attr_key => $slugs) {
            $new_combinations = [];
            foreach ($combinations as $combo) {
                foreach ($slugs as $slug) {
                    $new_combo = $combo;
                    $new_combo[$attr_key] = $slug;
                    $new_combinations[] = $new_combo;
                }
            }
            $combinations = $new_combinations;
        }

        // 为每个属性组合生成对应变体条目
        foreach ($combinations as $combo) {
            $new_variation = $variation;
            $new_variation['attributes'] = array_merge($fixed_attributes, $combo);
            $expanded_variations[] = $new_variation;
        }
    }

    echo '<options>';
    // 遍历展开后的变体列表,原有输出逻辑无需修改
    foreach ($expanded_variations as $variation) {
        echo "<option>
            {";
            foreach ($variation['attributes'] as $key=>$value) {
                $taxonomy = str_replace('attribute_', '', $key);
                $term = get_term_by('slug', $value, $taxonomy);
                echo "
                'label' : '". wc_attribute_label($taxonomy) ."',
                'value' : '". $term->name ."',
                ";
            }
        echo "
            'sku' : '". $variation['sku'] ."',
            'weight' : '". (!empty($variation['weight']) ? $variation['weight'] : 0) ."',
            'quantity' : ". ($variation['is_purchasable'] === true ? 10 : 0) .",
            'image' : '". $variation['image']['url'] ."',
            'price' : ". $variation['display_regular_price'] .",
            'discounted_price' : ". $variation['display_price'] ."
            }
        </option>
        ";
    }
    echo '</options>';
}
  • 该逻辑兼容多属性同时设置为ANY的场景,自动生成所有合法的属性组合
  • 展开生成的变体继承原ANY变体的价格、库存、图片、SKU等配置,和前台用户选择任意属性值时拿到的商品信息完全一致
  • 普通独立创建的变体不会被改动,完全兼容原有正常场景

若商品同时存在多个设置为ANY的变体(比如覆盖不同属性组合范围的变体),需要额外增加优先级判断逻辑,优先匹配属性固定值更多的变体,避免重复生成条目。单ANY变体的场景下上述代码可直接使用。

内容的提问来源于stack exchange,提问作者Deyan Kostadinov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 17:39:18