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

WooCommerce中WC()->session->set无法工作的问题排查求助

问题分析与调试修复方案

一、核心问题定位

  • 手动实例化WC_Session_Handler会破坏WooCommerce原生会话初始化流程,导致数据无法持久化
  • wpcf7_before_send_mail钩子触发时,WooCommerce会话可能未完成初始化,直接操作无效
  • woocommerce_checkout_before_customer_details钩子无$order_id参数,参数错误导致逻辑异常

二、分步调试与修复

1. 修正会话存储逻辑(替换原send_form_data_to_wc_session函数)

不要手动新建会话实例,依赖WooCommerce原生初始化机制,确保会话激活:

add_action('wpcf7_before_send_mail', 'send_form_data_to_wc_session', 5, 1);
function send_form_data_to_wc_session($contact_form) {
    $submission = WPCF7_Submission::get_instance();
    if($submission) {
        $posted_data = $submission->get_posted_data();
        if (!empty($posted_data['try'][0])) {
            // 确保WooCommerce会话已初始化
            if ( ! WC()->session->has_session() ) {
                WC()->session->set_customer_session_cookie( true );
            }
            // 存储表单数据到会话
            WC()->session->set('cf7_posted_data', $posted_data);
            // 调试:写入日志确认数据是否存储
            error_log('CF7 Session ID: ' . WC()->session->get_session_id());
            error_log('CF7 Stored Data: ' . print_r($posted_data, true));
        }
    }
}

2. 修正结账钩子的参数与逻辑(替换原wc_save_cf7_data_to_order函数)

该钩子无$order_id参数,直接获取会话数据,同时增加调试日志:

add_action('woocommerce_checkout_before_customer_details', 'wc_save_cf7_data_to_order');
function wc_save_cf7_data_to_order() {
    // 调试:输出当前会话ID,与存储时的ID对比
    error_log('Checkout Session ID: ' . WC()->session->get_session_id());
    
    $posted_data = WC()->session->get('cf7_posted_data');
    var_dump($posted_data);
    
    if(!empty($posted_data)) {
        foreach($posted_data as $key => $data) {
            echo '<b>', $key, ' : </b> ', $data, '<br />';
        }
        WC()->session->__unset('cf7_posted_data');
    } else {
        error_log('No CF7 data found in session');
    }
}

3. 调试会话一致性

  • 查看wp-content/debug.log,对比存储时和结账时的会话ID:
    • 若ID不一致,说明跳转前后会话丢失,检查缓存插件(如WP Rocket、W3 Total Cache),需排除CF7表单页和结账页的缓存
    • 若ID一致但数据为空,检查wp-config.php是否开启数据库存储会话:
      define('WC_SESSION_USE_DB', true); // 避免Cookie存储限制,强制用数据库存会话
      

4. 优化跳转逻辑(可选)

原JS跳转可能导致会话未及时写入,改用AJAX确认存储后再跳转:

document.addEventListener( 'wpcf7mailsent', function( event ) {
    if (jQuery("input[type='checkbox'][name='try[]']").is(':checked')) {
        jQuery.post(wc_params.ajax_url, {
            action: 'confirm_cf7_session',
            nonce: wc_params.wc_nonce
        }, function(response) {
            if(response.success) {
                location = 'http://www.thelittlegym.co.za/checkout/?add-to-cart=2506';
            }
        });
    } 
}, false );

同时在functions.php添加AJAX处理:

add_action('wp_ajax_confirm_cf7_session', 'confirm_cf7_session');
add_action('wp_ajax_nopriv_confirm_cf7_session', 'confirm_cf7_session');
function confirm_cf7_session() {
    check_ajax_referer('wc_nonce', 'nonce');
    wp_send_json_success();
}

三、最终数据持久化(写入订单自定义字段)

确认会话数据可用后,改用woocommerce_checkout_create_order钩子将数据写入订单元数据,方便后续API调用:

add_action('woocommerce_checkout_create_order', 'save_cf7_data_to_order_meta', 10, 2);
function save_cf7_data_to_order_meta($order, $data) {
    $posted_data = WC()->session->get('cf7_posted_data');
    if(!empty($posted_data)) {
        foreach($posted_data as $key => $value) {
            $order->update_meta_data('_cf7_' . $key, $value);
        }
        WC()->session->__unset('cf7_posted_data');
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 16:36:22