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

自定义WordPress插件调用WooCommerce REST API获取购物车报错排查

自定义REST端点获取WooCommerce购物车报错的问题分析与解决

你的代码存在几个关键问题,导致WC()->cart为null并触发报错,以下是具体问题和修复方案:

问题根源

报错Uncaught Error: Call to a member function get_cart() on null的核心原因:

  1. WooCommerce加载时机问题:插件可能在WooCommerce之前初始化,导致WC()全局对象未完全加载。
  2. REST API无状态特性:WooCommerce购物车依赖用户会话,但REST API默认不会自动初始化购物车会话,因此WC()->cart未被实例化。
  3. 权限回调过于宽松:__return_true允许所有请求访问,既不安全也未验证用户会话有效性。

修复方案

1. 确保插件在WooCommerce之后加载

在实例化类前添加WooCommerce存在检查,并通过plugins_loaded钩子延迟初始化,避免WooCommerce未加载时执行代码:

// 替换原有的new WoocommerceRestCart();
add_action('plugins_loaded', function() {
    if (class_exists('WooCommerce')) {
        new WoocommerceRestCart();
    }
});

同时在类的构造函数中也添加检查:

public function __construct()
{
    if (class_exists('WooCommerce')) {
        add_action('rest_api_init', array($this, 'set_woocommerce_cart_endpoint'));
    }
}

2. 手动初始化购物车会话

在回调函数中添加购物车初始化逻辑,确保WC()->cart被正确实例化:

public function get_woocommerce_cart_content( WP_REST_Request $request )
{
    // 初始化WooCommerce购物车会话
    if (is_null(WC()->cart)) {
        WC()->initialize_cart();
    }

    // 格式化购物车数据(直接返回get_cart()可能导致序列化问题)
    $cart_items = [];
    foreach (WC()->cart->get_cart() as $item_key => $item) {
        $product = $item['data'];
        $cart_items[] = [
            'product_id' => $product->get_id(),
            'name' => $product->get_name(),
            'quantity' => $item['quantity'],
            'single_price' => $product->get_price(),
            'subtotal' => $item['line_subtotal']
        ];
    }

    return rest_ensure_response([
        'cart_items' => $cart_items,
        'total_items' => WC()->cart->get_cart_contents_count(),
        'cart_total' => WC()->cart->get_total()
    ]);
}

3. 修复权限回调并验证会话

将宽松的权限回调改为验证用户登录状态或有效WooCommerce会话,确保请求合法:

'permissions_callback' => function() {
    // 允许登录用户或持有有效WooCommerce会话的访客访问
    return is_user_logged_in() || isset($_COOKIE[WC()->session->get_cookie_name()]);
}

4. Postman测试注意事项

由于REST API是无状态的,Postman请求需要手动携带用户的WooCommerce会话Cookie:

  • 在浏览器登录你的WordPress站点,复制woocommerce_session_*开头的Cookie值。
  • 在Postman的请求头中添加Cookie字段,值为复制的Cookie内容。

完整修复后的代码

class WoocommerceRestCart {

    public function __construct()
    {
        if (class_exists('WooCommerce')) {
            add_action('rest_api_init', array($this, 'set_woocommerce_cart_endpoint'));
        }
    }

    public function set_woocommerce_cart_endpoint()
    {
        register_rest_route( 
            'customshop', 
            '/cart', 
            array(
                'methods' => 'GET', // 官方推荐使用methods而非method
                'callback' => array( $this, 'get_woocommerce_cart_content' ),
                'permissions_callback' => function() {
                    return is_user_logged_in() || isset($_COOKIE[WC()->session->get_cookie_name()]);
                }
            ) 
        );
    }

    public function get_woocommerce_cart_content( WP_REST_Request $request )
    {
        if (is_null(WC()->cart)) {
            WC()->initialize_cart();
        }

        $cart_items = [];
        foreach (WC()->cart->get_cart() as $item_key => $item) {
            $product = $item['data'];
            $cart_items[] = [
                'product_id' => $product->get_id(),
                'name' => $product->get_name(),
                'quantity' => $item['quantity'],
                'single_price' => $product->get_price(),
                'subtotal' => $item['line_subtotal']
            ];
        }

        return rest_ensure_response([
            'cart_items' => $cart_items,
            'total_items' => WC()->cart->get_cart_contents_count(),
            'cart_total' => WC()->cart->get_total()
        ]);
    }

}

add_action('plugins_loaded', function() {
    if (class_exists('WooCommerce')) {
        new WoocommerceRestCart();
    }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:17:42