WooCommerce中无法更新ACF自定义字段问题求助
问题:无法通过函数更新ACF自定义字段提取订单追踪号
我写了个函数,用来从订单备注里提取追踪号(搞不懂插件开发者为啥不把追踪号存到订单元数据里)。逻辑看起来没问题,但ACF字段始终不更新,我漏了什么?
// add_action( 'woocommerce_after_order_object_save', 'find_tracking', 10, 1); // Also tried, it runs function 3 times add_action( 'save_post_shop_order', 'pax_find_tracking', 10, 1); function find_tracking ($order_id) { global $wpdb; $order = wc_get_order( $order_id ); $ID = $order->get_id(); $status = $order->get_status(); if ('completed' == $status) { // it's for testing $table_perfixed = $wpdb->prefix . 'comments'; $sql = "SELECT `comment_content` FROM $table_perfixed WHERE `comment_post_ID` = $ID AND `comment_content` LIKE '%Shipment data sent to server%'"; $result = $wpdb->get_var($sql); // checked, correct unique result if ($result) { $result = mb_substr($result, 44); // checked, correct tracking number update_field('my_tracking_field', $result, $ID); // Also tried without $ID //$order->add_order_note($result); // Checked result — it's string, not empty, $result is fine } } }
排查方向与修复方案
- ACF字段键错误:
update_field第一个参数必须用字段的字段键(比如field_64abc123def456),不是字段的显示名称。去ACF字段编辑页面查看字段键,替换掉my_tracking_field。 - 订单元数据标识错误:ACF针对WooCommerce订单存储自定义字段时,需要用
'order_' . $order_id作为第三个参数,而不是直接传订单ID。直接传ID会导致ACF无法定位到对应的订单元数据。 - 钩子时机不合适:
save_post_shop_order会在订单保存时多次触发,可能在订单状态还未完全更新为completed时就执行。改用woocommerce_order_status_completed钩子,仅在订单状态变为completed时触发,避免时机偏差。 - SQL注入风险与查询优化:直接将
$ID拼接进SQL存在安全隐患,改用$wpdb->prepare处理参数:$sql = $wpdb->prepare( "SELECT `comment_content` FROM $table_perfixed WHERE `comment_post_ID` = %d AND `comment_content` LIKE %s", $ID, '%Shipment data sent to server%' ); - 调试验证:在
update_field后添加var_dump(update_field(...));,如果返回false说明更新失败,可进一步排查字段键或参数;也可用get_field('你的字段键', 'order_' . $order_id)验证是否能读取到值。
修复后的完整代码
add_action( 'woocommerce_order_status_completed', 'pax_find_tracking', 10, 1); function pax_find_tracking ($order_id) { global $wpdb; $order = wc_get_order( $order_id ); $ID = $order->get_id(); $table_perfixed = $wpdb->prefix . 'comments'; $sql = $wpdb->prepare( "SELECT `comment_content` FROM $table_perfixed WHERE `comment_post_ID` = %d AND `comment_content` LIKE %s", $ID, '%Shipment data sent to server%' ); $result = $wpdb->get_var($sql); if ($result) { $tracking_number = mb_substr($result, 44); // 替换成你的ACF字段键 update_field('field_xxxxxxxxx', $tracking_number, 'order_' . $ID); // 可选:添加订单备注验证结果 $order->add_order_note('提取到追踪号:' . $tracking_number); } }
内容的提问来源于stack exchange,提问作者Demuri Celidze
相关产品推荐
相关产品推荐

