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

传递参数无法显示WooCommerce自定义后台通知问题排查

问题:传递参数的WooCommerce后台通知不生效(闭包方案失效)

尝试通过向函数传递参数显示WooCommerce自定义后台通知,使用闭包方案后未生效,但直接使用字符串而非传递$message变量时,通知能正常显示。相关代码如下:

原PHP代码

function custom_woocommerce_admin_notice( $message ) {
    
add_action( 'admin_notices', function() use ( $message ) {
    wc_get_logger()->info('Order Message: '.$message ) ;
    if ( function_exists( 'get_current_screen' ) ) {
        $screen = get_current_screen();
        if ( isset( $screen->id ) && $screen->id === 'edit-shop_order' ) {
            // Check if the notice has already been dismissed
            if ( ! get_option( 'custom_woocommerce_admin_notice_dismissed' ) ) {
                ?>
                <div class="notice notice-success is-dismissible woocommerce-notice">
                    <p><?php _e( 'Hello: '.$message , 'text-domain' ); ?></p>
                </div>
                <?php
            }
        }
    }
    });
}

add_action( 'admin_notices', 'custom_woocommerce_admin_notice' );


function custom_woocommerce_admin_notice_dismissed() {
    update_option( 'custom_woocommerce_admin_notice_dismissed', 1 );
}
add_action( 'wp_ajax_custom_woocommerce_admin_notice_dismissed', 'custom_woocommerce_admin_notice_dismissed' );

function enqueue_custom_woocommerce_admin_notice_script( $hook ) {
    // Check if we are on the WooCommerce orders page
    if ( function_exists( 'get_current_screen' ) ) {
        $screen = get_current_screen();
        if ( isset( $screen->id ) && $screen->id === 'edit-shop_order' ) {
            wp_enqueue_script( 'custom_woocommerce_admin_notice_script', get_template_directory_uri() . '/js/custom-woocommerce-admin-notice.js', array( 'jquery' ), null, true );
        }
    }
}
add_action( 'admin_enqueue_scripts', 'enqueue_custom_woocommerce_admin_notice_script' );

原函数调用方式

custom_woocommerce_admin_notice( $message );

原JS脚本

jQuery(document).ready(function($) {
    $('.notice.is-dismissible').on('click', '.notice-dismiss', function() {
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'custom_woocommerce_admin_notice_dismissed'
            }
        });
    });
});

问题根源

核心问题是钩子嵌套导致时序错误:
你把custom_woocommerce_admin_notice挂到了admin_notices钩子上,当该钩子触发执行这个函数时,你又在函数内部添加了另一个admin_notices的闭包钩子。但此时admin_notices已经处于执行流程中,新添加的钩子不会在本次请求中生效,闭包代码永远不会被执行,自然看不到通知。

另外,虽然闭包的use ($message)语法正确,但因为闭包从未被调用,所以日志也不会输出,参数传递的逻辑根本没机会运行。


修复方案

不需要嵌套钩子,改用临时存储传递参数(比如WordPress的transient),直接在admin_notices钩子函数中读取并显示通知。

修改后的PHP代码

// 用于存储要显示的通知消息
function set_custom_woocommerce_admin_notice( $message ) {
    // 存储5分钟有效期的临时消息,避免残留
    set_transient( 'custom_woocommerce_admin_notice_message', $message, MINUTE_IN_SECONDS * 5 );
}

// 显示通知的钩子函数,直接挂到admin_notices
function custom_woocommerce_admin_notice() {
    // 读取临时消息
    $message = get_transient( 'custom_woocommerce_admin_notice_message' );
    if ( empty( $message ) ) {
        return;
    }

    wc_get_logger()->info('Order Message: '.$message ) ;
    if ( function_exists( 'get_current_screen' ) ) {
        $screen = get_current_screen();
        if ( isset( $screen->id ) && $screen->id === 'edit-shop_order' ) {
            // 检查是否已关闭通知
            if ( ! get_option( 'custom_woocommerce_admin_notice_dismissed' ) ) {
                ?>
                <div class="notice notice-success is-dismissible woocommerce-notice">
                    <p><?php _e( 'Hello: '.$message , 'text-domain' ); ?></p>
                </div>
                <?php
                // 显示后删除临时消息,避免重复显示
                delete_transient( 'custom_woocommerce_admin_notice_message' );
            }
        }
    }
}
add_action( 'admin_notices', 'custom_woocommerce_admin_notice' );

// 保留原有的关闭通知AJAX逻辑
function custom_woocommerce_admin_notice_dismissed() {
    update_option( 'custom_woocommerce_admin_notice_dismissed', 1 );
}
add_action( 'wp_ajax_custom_woocommerce_admin_notice_dismissed', 'custom_woocommerce_admin_notice_dismissed' );

// 保留原有的脚本加载逻辑
function enqueue_custom_woocommerce_admin_notice_script( $hook ) {
    if ( function_exists( 'get_current_screen' ) ) {
        $screen = get_current_screen();
        if ( isset( $screen->id ) && $screen->id === 'edit-shop_order' ) {
            wp_enqueue_script( 'custom_woocommerce_admin_notice_script', get_template_directory_uri() . '/js/custom-woocommerce-admin-notice.js', array( 'jquery' ), null, true );
        }
    }
}
add_action( 'admin_enqueue_scripts', 'enqueue_custom_woocommerce_admin_notice_script' );

修改后的函数调用方式

// 不再直接调用显示函数,而是先存储消息
set_custom_woocommerce_admin_notice( $message );

说明

  1. 用set_transient存储消息:临时存储会自动过期,避免消息长期残留;
  2. 直接在admin_notices钩子函数中读取消息:确保代码在钩子触发时执行,不会错过时机;
  3. 显示后删除临时消息:防止刷新页面时重复显示通知;
  4. 原有关闭通知和脚本加载逻辑保持不变,无需修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 13:37:06