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

开发WooCommerce众筹插件调用wc_get_product报错如何解决?

问题根因

两个报错本质都是WooCommerce核心函数调用时机太早导致:

  • 你的插件加载顺序优先于WooCommerce,直接调用wc_get_product()时函数还未被定义
  • 手动引入WooCommerce主文件后,调用函数时WooCommerce还未完成初始化流程,触发官方的时机校验错误
  • 额外问题:SQL查询返回的是对象,你直接将对象传入wc_get_product()而非对象下的product_id属性,也会导致调用失败

修复步骤

1. 修改主插件文件

调整代码逻辑,等WooCommerce初始化完成后再加载功能代码,同时增加WooCommerce未激活的容错提示,代码如下:

<?php
/**
 * Plugin Name: xxx
 * Plugin URI: xxx
 * Description: xxx
 * Version: xxx
 * Author: xxx.com
 * Author URI: xxx
 */

defined( 'ABSPATH' ) or die( 'Plugin file cannot be accessed directly.' );

// 校验WooCommerce是否激活
add_action( 'plugins_loaded', 'cfdg_check_woocommerce_active' );
function cfdg_check_woocommerce_active() {
    if ( ! class_exists( 'WooCommerce' ) ) {
        add_action( 'admin_notices', 'cfdg_woocommerce_missing_notice' );
        return;
    }
    // WooCommerce已激活,加载功能文件、注册后台菜单
    require(dirname(__FILE__).'/shortcodes.php');
    add_action("admin_menu","cfdg_add_admin_menu");
}

// WooCommerce未激活的后台提示
function cfdg_woocommerce_missing_notice() {
    ?>
    <div class="notice notice-error">
        <p>众筹插件需要先安装并启用WooCommerce才能正常使用。</p>
    </div>
    <?php
}

function cfdg_add_admin_menu(){
    add_menu_page("Crowdfunding","Crowdfunding", "manage_options", "cfdg-admin", "cfdg_add_page", "dashicons-money");
}
function cfdg_add_page(){
    require (dirname(__FILE__).'/adminmenu.php');
}
?>

2. 修改shortcodes.php文件

取消全局作用域的函数调用,将已筹金额计算逻辑放到短码回调中执行,同时修复参数传递错误,代码如下:

<?php

$targetMoney = 30000;

function cfdg_getEarnedMoney() {
    global $wpdb;
    
    $cdfg_money_to_return = 0;
    // 替换硬编码的表前缀为动态获取,适配自定义表前缀的站点
    $sql = $wpdb->prepare('SELECT ml.product_id FROM %i AS pl 
    JOIN %i AS ml ON pl.product_id = ml.product_id
    JOIN %i AS wp ON wp.ID = pl.order_id WHERE LOCATE("crowdfunding",sku) AND (wp.post_status = "wc-processing" OR wp.post_status = "wc-completed");',
    $wpdb->prefix . 'wc_order_product_lookup',
    $wpdb->prefix . 'wc_product_meta_lookup',
    $wpdb->posts
    );
    $results = $wpdb->get_results($sql);
    if(!$results) return 0;

    foreach($results as $res){
        // 传入查询到的product_id属性,而非整个结果对象
        $cdfg_produkcik = wc_get_product($res->product_id);
        if(!$cdfg_produkcik) continue; // 增加商品不存在的容错
        $cdfg_product_price= $cdfg_produkcik->get_price();
        $cdfg_money_to_return += floatval($cdfg_product_price);
    }
    return $cdfg_money_to_return ;
}

//PROGRESS BAR
add_shortcode('cfdg_progress_bar', 'cfdg_func_progress_bar');

function cfdg_func_progress_bar(){
    global $targetMoney;
    // 在短码调用时才计算已筹金额,此时WooCommerce已完成初始化
    $earnedMoney = cfdg_getEarnedMoney();
    // 短码回调需return内容而非直接echo,避免输出位置错乱
    return "Earned: ".$earnedMoney." from: ".$targetMoney." required";
}
//END OF PROGRESS BAR
?>

其他优化建议

  • 已筹金额计算可增加缓存逻辑,避免每次短码渲染都查库,降低数据库压力
  • 金额输出可使用wc_price()函数格式化,适配WooCommerce的货币设置
  • 可以在插件后台增加目标金额的配置项,替代硬编码的30000数值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 14:48:02