传递参数无法显示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 );
说明
- 用
set_transient存储消息:临时存储会自动过期,避免消息长期残留; - 直接在
admin_notices钩子函数中读取消息:确保代码在钩子触发时执行,不会错过时机; - 显示后删除临时消息:防止刷新页面时重复显示通知;
- 原有关闭通知和脚本加载逻辑保持不变,无需修改。
内容的提问来源于stack exchange,提问作者mrslope
相关产品推荐
相关产品推荐

