WooCommerce订单保存后存储自定义商品元数据失败求解决方法
问题原因
- 变量名未定义错误:代码中通过
wc_get_product()获取到的产品实例赋值给了$product变量,但后续更新元数据时调用的是未定义的$final_product变量,属于基础语法错误,代码执行到此处会直接抛出致命错误,无法执行后续的保存元数据逻辑。 - 状态判断逻辑倒置:当前代码逻辑为「如果订单状态属于指定的4种状态,直接终止执行」,和你要实现的「特定状态下保存商品元数据」的需求完全相反,符合你要求的状态反而不会执行元数据写入操作。
- 钩子选择合理性问题:
save_post_shop_order是WordPress原生的文章保存钩子,触发时WooCommerce的订单状态、商品项等数据可能还未完成更新写入,此时获取到的订单状态大概率是更新前的旧值,会导致判断逻辑失效。 - 订单实例化方式不严谨:直接使用
new WC_Order()实例化订单,若传入的ID不是有效订单ID会直接抛出致命错误,容错性差。
修复方案
1. 钩子优化
优先使用WooCommerce官方提供的woocommerce_after_order_object_save钩子,触发时订单数据已经完成全量写入,可保证获取到的订单状态、商品项都是最新值。
2. 修正后代码
add_action('woocommerce_after_order_object_save', function (\WC_Order $order, bool $data_store): void { // 定义需要触发元数据保存的订单状态 $target_status = ['processing', 'on-hold', 'to-order', 'needed']; $order_status = $order->get_status(); // 非指定状态直接终止执行 if (!in_array($order_status, $target_status)) { return; } // 遍历订单商品项 foreach ($order->get_items() as $item) { $product_id = $item->get_product_id(); $product = wc_get_product($product_id); // 跳过无效商品避免报错 if (!$product) { continue; } // 修正变量名,执行元数据更新保存 $product->update_meta_data('_test', '_test'); $product->save(); } }, 10, 2);
3. 验证方法
修改代码后,创建/更新一个符合指定状态的订单,到wp_postmeta数据表中搜索post_id为对应商品ID、meta_key为_test的记录,即可查看到写入的元数据。
内容的提问来源于stack exchange,提问作者Vladimir Kyatipov
相关产品推荐
相关产品推荐

