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

WooCommerce自定义代码导致更新订单状态时网站崩溃

问题:WordPress后台重发优惠券订单通知时触发严重错误

在WordPress后台操作订单(如通过「订单操作」→选择操作→重新发送订单通知)时,网站出现严重错误,该问题仅在使用优惠券的特定订单上触发。

错误信息

An error of type E_ERROR was caused in line 21 of the file /usr/www/users/africgebks/wp-content/themes/woodmart-child/functions.php. Error message: Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given in /usr/www/users/africgebks/wp-content/themes/woodmart-child/functions.php:21
Stack trace:
#0 /usr/www/users/africgebks/wp-includes/class-wp-hook.php(310): display_applied_coupons(Object(Automattic\WooCommerce\Admin\Overrides\Order), true, false, Object(WC_Email_New_Order))
#1 /usr/www/users/africgebks/wp-includes/class-wp-hook.php(334): WP_Hook->apply_filters('', Array)
#2 /usr/www/users/africgebks/wp-includes/plugin.php(517): WP_Hook->do_action(Array)
#3 /usr/www/users/africgebks/wp-content/plugins/woocommerce/templates/emails/admin-new-order.php(35): do_action('woocommerce_ema...', Object(Automattic\WooCommerce\Admin\Overrides\Order), true, false, Object(WC_Email_New_Order))
#4 /usr/www/users/africgebks/wp-content/plugins/woocommerce/includes/wc-core-functions.php(345): include('/usr/www/users/...')
#5 /usr/www/users/africgebks/wp-content/plugins/woocommerce/includes/wc-core-functions.php(364): wc_get_template('emails/admin-ne...', Array, '', '')
#6 /usr/www/users/africgebks/wp-content/plugins/woocommerce/includes/emails/class-wc-email-new-order.php(134): wc_get_template_html('emails/admin-ne...', Array)
#7 /usr/www/users/africgebks/wp-content/plugins/woocommerce/includes/emails/class-wc-email.php(581): WC_Email_New_Order->get_content_html()
#8 /usr/www/users/africgebks/wp-content/plugins/woocommerce/includes/emails/class-wc-email-new-order.php(111): WC_Email->get_content()
#9 /usr/www/users/africgebks/wp-content/plugins/woocommerce/includes/admin/meta-boxes/class-wc-meta-box-order-actions.php(156): WC_Email_New_Order->trigger(14992, Object(Automattic\WooCommerce\Admin\Overrides\Order), true)
#10 /usr/www/users/africgebks/wp-includes/class-wp-hook.php(310): WC_Meta_Box_Order_Actions::save(14992, Object(WP_Post))
#11 /usr/www/users/africgebks/wp-includes/class-wp-hook.php(334): WP_Hook->apply_filters(NULL, Array)
#12 /usr/www/users/africgebks/wp-includes/plugin.php(517): WP_Hook->do_action(Array)
#13 /usr/www/users/africgebks/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-meta-boxes.php(258): do_action('woocommerce_pro...', 14992, Object(WP_Post))
#14 /usr/www/users/africgebks/wp-includes/class-wp-hook.php(312): WC_Admin_Meta_Boxes->save_meta_boxes(14992, Object(WP_Post))
#15 /usr/www/users/africgebks/wp-includes/class-wp-hook.php(334): WP_Hook->apply_filters('', Array)
#16 /usr/www/users/africgebks/wp-includes/plugin.php(517): WP_Hook->do_action(Array)
#17 /usr/www/users/africgebks/wp-includes/post.php(4751): do_action('save_post', 14992, Object(WP_Post), true)
#18 /usr/www/users/africgebks/wp-includes/post.php(4853): wp_insert_post(Array, false, true)
#19 /usr/www/users/africgebks/wp-admin/includes/post.php(445): wp_update_post(Array)
#20 /usr/www/users/africgebks/wp-admin/post.php(227): edit_post()
#21 {main}
  thrown

问题根源

错误来自Woodmart子主题functions.php中的自定义优惠券显示代码,原代码如下:

// The email function hooked that display the text
add_action( 'woocommerce_email_order_details', 'display_applied_coupons', 10, 4 );
function display_applied_coupons( $order, $sent_to_admin, $plain_text, $email ) {

    // Only for admins and when there at least 1 coupon in the order
    if ( ! $sent_to_admin && count($order->get_items('coupon') ) == 0 ) return;

    foreach( $order->get_items('coupon') as $coupon ){
        $coupon_codes[] = $coupon->get_code();
    }
    // For one coupon
    if( count($coupon_codes) == 1 ){
        $coupon_code = reset($coupon_codes);
        echo '<p>'.__( 'Coupon Used: ').$coupon_code.'<p>';
    } 
    // For multiple coupons
    else {
        $coupon_codes = implode( ', ', $coupon_codes);
        echo '<p>'.__( 'Coupons Used: ').$coupon_codes.'<p>';
    }
}

错误分析

  1. 条件判断逻辑错误:原代码仅在「非管理员且无优惠券」时返回,但管理员操作无优惠券订单时,代码会继续执行,此时$order->get_items('coupon')可能返回null或空,导致$coupon_codes未初始化。
  2. PHP8.1类型严格检查:PHP8.1对count()函数的参数要求严格,必须是可计数类型(数组/Countable对象),未定义的$coupon_codes或null会触发TypeError。
  3. 未处理get_items返回值:$order->get_items('coupon')在某些情况下可能返回null,而非空数组,直接遍历会导致后续变量未定义。

修正后的代码

// 在订单邮件中显示使用的优惠券
add_action( 'woocommerce_email_order_details', 'display_applied_coupons', 10, 4 );
function display_applied_coupons( $order, $sent_to_admin, $plain_text, $email ) {
    // 获取订单中的优惠券项目,确保是可计数类型
    $coupon_items = $order->get_items('coupon');
    $coupon_items = is_countable($coupon_items) ? $coupon_items : [];

    // 仅针对管理员,且订单存在优惠券时执行
    if ( !$sent_to_admin || count($coupon_items) === 0 ) {
        return;
    }

    $coupon_codes = [];
    foreach( $coupon_items as $coupon ){
        $coupon_codes[] = $coupon->get_code();
    }

    // 显示单个优惠券
    if( count($coupon_codes) === 1 ){
        $coupon_code = reset($coupon_codes);
        echo '<p>'.__( '使用优惠券: ').$coupon_code.'</p>';
    } 
    // 显示多个优惠券
    else {
        $coupon_codes_str = implode( ', ', $coupon_codes);
        echo '<p>'.__( '使用优惠券: ').$coupon_codes_str.'</p>';
    }
}

环境信息

  • WordPress版本:6.3
  • 启用主题:Woodmart Child(1.0.0)
  • PHP版本:8.1.22

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 13:05:20