自定义WordPress插件调用WooCommerce REST API获取购物车报错排查
自定义REST端点获取WooCommerce购物车报错的问题分析与解决
你的代码存在几个关键问题,导致WC()->cart为null并触发报错,以下是具体问题和修复方案:
问题根源
报错Uncaught Error: Call to a member function get_cart() on null的核心原因:
- WooCommerce加载时机问题:插件可能在WooCommerce之前初始化,导致
WC()全局对象未完全加载。 - REST API无状态特性:WooCommerce购物车依赖用户会话,但REST API默认不会自动初始化购物车会话,因此
WC()->cart未被实例化。 - 权限回调过于宽松:
__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
相关产品推荐
相关产品推荐

