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

WooCommerce变量产品自定义字段取值及函数间传值问题

解决WooCommerce自定义变量字段获取与函数间传值问题

嘿,我来帮你搞定这个问题!你已经成功在WooCommerce变量产品中创建了自定义字段_num_cubic_var,接下来我们一步步解决你的两个核心需求:

一、在ut_before_calculate_totals中获取_num_cubic_var的值

在购物车总价计算的函数里,每个购物车项都包含了对应的变体ID,你可以直接通过这个ID拉取自定义字段的值。我帮你优化了原函数,同时补上了必要的钩子挂载和防重复计算的判断(这是WooCommerce开发的最佳实践):

add_action( 'woocommerce_before_calculate_totals', 'ut_before_calculate_totals', 10, 1 );
function ut_before_calculate_totals( $cart_obj ) {
    // 避免后台重复触发计算(仅在前端或AJAX请求时执行)
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
        return;
    }

    foreach( $cart_obj->get_cart() as $key => $value ) {
        // 获取当前购物车项对应的变体ID
        $variation_id = $value['data']->get_id();
        // 拉取自定义字段值
        $num_cubic_var = get_post_meta( $variation_id, '_num_cubic_var', true );
        
        // 这里可以用$num_cubic_var做你需要的业务逻辑,比如结合它调整价格
        if ( ! empty( $num_cubic_var ) ) {
            // 用WooCommerce内置方法获取价格(比直接读元数据更可靠)
            $base_price = $value['data']->get_sale_price() ? $value['data']->get_sale_price() : $value['data']->get_regular_price();
            // 结合自定义字段计算新价格
            $adjusted_price = $base_price * $num_cubic_var;
            $value['data']->set_price( $adjusted_price );
        }
    }
}

二、函数之间传递值的几种实用方式

在WordPress/WooCommerce生态里,有几种常用的函数间传值方案,你可以根据场景选择:

1. 全局变量(简单但需谨慎)

适合快速临时传值,但要注意命名冲突问题:

// 在第一个函数中设置全局变量
function set_cubic_value() {
    global $shared_cubic_value;
    $shared_cubic_value = get_post_meta( get_the_ID(), '_num_cubic_var', true );
}

// 在第二个函数中获取全局变量
function use_cubic_value() {
    global $shared_cubic_value;
    if ( isset( $shared_cubic_value ) ) {
        // 这里使用值做逻辑处理
        echo $shared_cubic_value;
    }
}

2. WooCommerce会话(适合购物车/用户场景)

如果值和当前用户或购物车相关,用WC会话存储更安全:

// 保存值到会话
function save_cubic_to_session( $variation_id ) {
    if ( WC()->session->has_session() || is_user_logged_in() ) {
        $num_cubic_var = get_post_meta( $variation_id, '_num_cubic_var', true );
        WC()->session->set( 'user_selected_cubic', $num_cubic_var );
    }
}

// 从会话中读取值
function get_cubic_from_session() {
    $num_cubic_var = WC()->session->get( 'user_selected_cubic' );
    if ( ! empty( $num_cubic_var ) ) {
        // 使用值做业务逻辑
    }
}

3. 钩子参数传递(最推荐的WordPress方式)

通过自定义钩子传递参数,完全符合WordPress的设计理念,避免全局变量的隐患:

// 在某个函数中触发自定义钩子并传递值
function trigger_custom_hook() {
    $variation_id = get_the_ID();
    $num_cubic_var = get_post_meta( $variation_id, '_num_cubic_var', true );
    // 触发钩子并传递参数
    do_action( 'custom_cubic_value_ready', $num_cubic_var );
}

// 监听钩子并接收参数
add_action( 'custom_cubic_value_ready', 'handle_cubic_value', 10, 1 );
function handle_cubic_value( $num_cubic_var ) {
    // 直接使用传递过来的$num_cubic_var
    echo "当前立方值:{$num_cubic_var}";
}

4. 静态类变量(适合复杂业务场景)

用类的静态变量规范管理共享值,适合多函数联动的复杂逻辑:

class CubicValueManager {
    public static $current_cubic_value;

    // 设置值
    public static function set_value( $variation_id ) {
        self::$current_cubic_value = get_post_meta( $variation_id, '_num_cubic_var', true );
    }

    // 获取值
    public static function get_value() {
        return self::$current_cubic_value;
    }
}

// 使用示例:设置值
CubicValueManager::set_value( get_the_ID() );
// 使用示例:获取值
$cubic_value = CubicValueManager::get_value();

三、整合优化你的完整代码

最后我把你所有的代码整合优化了一遍,确保逻辑更严谨、写法更规范:

// 添加自定义字段到变量产品编辑页面
add_action( 'woocommerce_product_after_variable_attributes', 'num_cubicmeters_fields', 10, 3 );
function num_cubicmeters_fields( $loop, $variation_data, $variation ) {
    woocommerce_wp_text_input( array(
        'id' => '_num_cubic_var[' . $variation->ID . ']',
        'label' => 'Количество кубометров',
        'description' => 'Укажи количество кубометров',
        'desc_tip' => 'true',
        'placeholder' => 'Количество кубометров, м3',
        'type' => 'number',
        'custom_attributes' => array(
            'step' => 'any',
            'min' => '0',
        ),
        'value' => get_post_meta( $variation->ID, '_num_cubic_var', true ),
    ) );
}

// 保存自定义字段值(增加空值处理)
add_action( 'woocommerce_save_product_variation', 'art_save_variation_settings_fields', 10, 2 );
function art_save_variation_settings_fields( $post_id ) {
    if ( isset( $_POST['_num_cubic_var'][ $post_id ] ) && ! empty( $_POST['_num_cubic_var'][ $post_id ] ) ) {
        update_post_meta( $post_id, '_num_cubic_var', esc_attr( $_POST['_num_cubic_var'][ $post_id ] ) );
    } else {
        // 若值为空则删除元数据,避免冗余
        delete_post_meta( $post_id, '_num_cubic_var' );
    }
}

// 加载自定义字段到前端变体数据(优化HTML拼接和转义)
add_filter( 'woocommerce_available_variation', 'load_variation_settings_fields' );
function load_variation_settings_fields( $variations ) {
    $variations_num_cubic = get_post_meta( $variations['variation_id'], '_num_cubic_var', true );
    if ( ! empty( $variations_num_cubic ) ) {
        $variations['_num_cubic_var'] = sprintf(
            '<div class="num-cubicmeters-prod"><span>Количество Кубометров</span>%s м3</div>',
            esc_html( $variations_num_cubic )
        );
    }
    return $variations;
}

// 购物车计算总价时获取自定义字段并处理
add_action( 'woocommerce_before_calculate_totals', 'ut_before_calculate_totals', 10, 1 );
function ut_before_calculate_totals( $cart_obj ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
        return;
    }

    foreach( $cart_obj->get_cart() as $key => $value ) {
        $variation_id = $value['data']->get_id();
        $num_cubic_var = get_post_meta( $variation_id, '_num_cubic_var', true );
        
        if ( ! empty( $num_cubic_var ) ) {
            $base_price = $value['data']->get_sale_price() ?: $value['data']->get_regular_price();
            $adjusted_price = $base_price * $num_cubic_var;
            $value['data']->set_price( $adjusted_price );
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 21:04:09