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

新手求助:$wpdb->get_results在客户邮件正常,管理员邮件返回空数组

排查思路:同代码下管理员邮件订单项为空的问题

嘿,新手朋友别慌!这种“同一代码在不同场景下结果不一样”的问题其实挺常见的,我帮你梳理几个最可能的原因和排查方向,应该能帮你找到症结👇

1. 订单数据的写入时机差异

这是最常见的原因:第一次发送管理员邮件时,订单的订单项可能还没完全写入数据库。

  • 客户下单时,系统的流程是先创建订单主体,再添加订单项,最后触发邮件通知。如果你的代码在订单项还没保存完成时就执行了,自然拿不到数据;而后台重发邮件时,订单已经完全创建完毕,所有数据都稳稳存在数据库里了。
  • 举个例子:如果你的代码是挂在woocommerce_new_order钩子上(假设你用的是WooCommerce),这个钩子触发时订单刚创建,订单项可能还没被关联进去;但后台重发是直接调用已完成的订单对象,数据自然齐全。

2. 代码上下文/用户权限的细微差别

虽然可能性稍低,但也要排查:

  • 前台触发管理员邮件时,代码的执行上下文可能是“访客”或者“下单客户”身份,而后台重发时是管理员身份。如果你的自定义查询涉及到权限校验(比如某些数据需要管理员权限才能读取),就会出现这种差异。
  • 可以加个日志看看当前执行代码的用户ID,对比两次的差异:
    error_log("当前执行用户ID: " . get_current_user_id());
    

3. 自定义SQL vs WooCommerce内置方法的问题

如果你是用自己写的SQL查询订单项(比如SELECT * FROM wp_woocommerce_order_items WHERE order_id = X),很可能错过WooCommerce内部的数据同步流程:

  • 系统创建订单时,可能会先在内存里处理订单项,再批量写入数据库。直接写SQL可能在第一次触发时,数据库还没收到这些数据;而用WooCommerce的内置方法$order->get_items()会优先从内存的订单对象里取数据,更可靠。
  • 建议替换成官方方法,尽量避免直接操作数据库表。

4. 钩子优先级的问题

如果你的代码是通过钩子注入到邮件模板里的,钩子的优先级可能导致它执行得太早:

  • 比如默认钩子优先级是10,如果你的代码在WC还没把订单项加载到订单对象之前就跑了,拿到的就是空数组;而后台重发时,流程的执行顺序可能不同,或者钩子触发时机更晚。
  • 试试把钩子的优先级调大(比如改成20),让它晚一点执行:
    add_action('woocommerce_email_order_details', 'your_custom_function', 20, 4);
    

最有效的排查步骤:加日志对比

不管哪种原因,加日志看差异都是最快的排查方法:
在你的email-order-items.php代码里添加这些日志:

// 获取订单ID
$order_id = $order->get_id();
error_log("=== 邮件触发记录:订单ID $order_id ===");
error_log("触发时间:" . date('Y-m-d H:i:s'));
// 获取订单项(用你的方法或者官方方法)
$items = $order->get_items(); // 替换成你的查询代码
error_log("订单项数量:" . count($items));
error_log("订单项详情:" . print_r($items, true));

然后开启WordPress的调试模式(把wp-config.php里的WP_DEBUG设为true,WP_DEBUG_LOG设为true),之后触发一次新订单,再后台重发一次,去wp-content/debug.log里对比两次的日志,就能清楚看到第一次为什么是空数组了。

慢慢来,这种问题排查清楚后,你对系统的执行流程会理解得更深~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:07:17