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

如何清除条件导航函数引发的nav-menu-template.php未定义属性警告?

WordPress会员导航切换函数的PHP警告修复方案

问题背景

我编写了一个根据用户登录状态及会员身份切换主导航的函数,代码如下:

function custm_navigation_args($args) {
    if(is_user_logged_in()) { 
        $memid = get_current_user_id();
        if ($memid != 0) {
            global $wpdb;
            $mems = $wpdb->get_results("select statement that grabs all users with specific membership ids");

            $memb_group = array();
            ksort($memb_group, SORT_NUMERIC);

            if (!empty($mems)) {
                foreach ($mems as $key => $item) {
                    $memb_meta = get_object_vars($item);
                    foreach ($memb_meta as $meta_in => $membdetails) {
                        $memb_group[$item->user_id]['memship'] = $memb_meta['memberships'];
                    }
                }

                $membprof = '';

                foreach($memb_group as $mmm) {
                    $membprof .= $mmm['memship'];
                    if (!isset( $args['theme_location']) || $args['theme_location'] == "") {
                       $args['theme_location'] = 'primary-menu';
                    }
                    if ($membprof == '2017' || $membprof == '2048') {
                        $args['menu'] = 36;
                    } else if ($membprof == '2031' || $membprof == '2050') {
                        $args['menu'] = 38;
                    } else if ($membprof == '44' || $membprof == '1557' || $membprof == '1936') {
                        $args['menu'] = 2;
                    } else if ($membprof == '2326' || $membprof == '536') {
                        $args['menu'] = 41;
                    } else if ($membprof == '2364' || $membprof == '2371') {
                        $args['menu'] = 42;
                    }                    
                }
            } else {
                $args['menu'] = 37; //Logged Out Menu
            }
        }
        return $args;
    }
}
add_filter( 'wp_nav_menu_args', 'custm_navigation_args' );

该函数可正常运行,但用户登录时错误日志会多次记录以下PHP警告:

  • PHP Warning: Undefined property: stdClass::$menu in ./wp-includes/nav-menu-template.php on line 125
  • PHP Warning: Undefined property: stdClass::$theme_location in ./wp-includes/nav-menu-template.php on line 129
  • PHP Warning: Undefined property: stdClass::$theme_location in ./wp-includes/nav-menu-template.php on line 134
  • PHP Warning: Undefined property: stdClass::$container in ./wp-includes/nav-menu-template.php on line 175
  • PHP Warning: Undefined property: stdClass::$depth in ./wp-includes/nav-menu-template.php on line 228
  • PHP Warning: Undefined property: stdClass::$menu_class in ./wp-includes/nav-menu-template.php on line 247

已通过wp_registered_nav_menus确认主题位置名称正确,移除主题位置定义语句后警告仍存在,错误日志重复记录3次,当前使用Divi主题。需要在保留原有功能的前提下清除这些警告。


问题根源

这些警告的核心原因是:

  1. 函数仅在用户登录时返回$args,未登录时无返回值,导致WordPress处理导航菜单时接收到NULL,而非预期的参数数组/对象,触发未定义属性警告。
  2. 代码中对$args的修改未保留WordPress导航菜单所需的默认属性,部分必要字段缺失。
  3. 会员数据处理存在冗余,$membprof拼接逻辑可能导致会员ID叠加,引发匹配错误。

修复后的完整代码

function custm_navigation_args($args) {
    // 合并原始参数与默认值,确保所有必要属性都存在
    $processed_args = wp_parse_args($args, array(
        'theme_location' => 'primary-menu',
        'menu' => '',
        'container' => 'div',
        'depth' => 0,
        'menu_class' => 'menu',
    ));

    if(is_user_logged_in()) { 
        $memid = get_current_user_id();
        if ($memid != 0) {
            global $wpdb;
            // 建议:优先使用会员插件API替代直接SQL查询,提升安全性
            $mems = $wpdb->get_results("select statement that grabs all users with specific membership ids");

            $memb_group = array();
            if (!empty($mems)) {
                foreach ($mems as $item) {
                    // 简化会员数据提取,避免冗余循环
                    $memb_group[$item->user_id]['memship'] = $item->memberships;
                }

                $membprof = '';
                foreach($memb_group as $mmm) {
                    // 单个用户通常对应一个会员组,直接赋值而非拼接
                    $membprof = $mmm['memship'];
                    break;
                }

                // 用switch替代多层elseif,逻辑更清晰
                switch($membprof) {
                    case '2017':
                    case '2048':
                        $processed_args['menu'] = 36;
                        break;
                    case '2031':
                    case '2050':
                        $processed_args['menu'] = 38;
                        break;
                    case '44':
                    case '1557':
                    case '1936':
                        $processed_args['menu'] = 2;
                        break;
                    case '2326':
                    case '536':
                        $processed_args['menu'] = 41;
                        break;
                    case '2364':
                    case '2371':
                        $processed_args['menu'] = 42;
                        break;
                    default:
                        // 匹配不到会员组时使用默认登录菜单
                        $processed_args['menu'] = 37;
                        break;
                }
            } else {
                $processed_args['menu'] = 37; // 无会员数据时的登录菜单
            }
        }
    } else {
        // 未登录状态设置对应菜单
        $processed_args['menu'] = 37;
    }

    // 确保任何场景都返回完整参数
    return $processed_args;
}
add_filter( 'wp_nav_menu_args', 'custm_navigation_args' );

关键修复说明

  1. 强制返回完整参数:新增未登录分支的返回逻辑,确保无论用户登录状态如何,都返回包含所有必要属性的参数数组,不会返回NULL。
  2. 保留默认属性:使用wp_parse_args合并原始参数和WordPress导航菜单的默认值,保证container、depth、menu_class等必填字段都存在,从根源避免未定义属性警告。
  3. 优化会员数据处理:
    • 移除冗余的get_object_vars循环,直接访问$item->memberships提取会员信息。
    • 将$membprof的拼接逻辑改为赋值,避免多会员ID叠加导致的匹配错误(单个用户通常仅对应一个会员组)。
    • 用switch语句替代多层elseif,代码结构更清晰,维护性更强。
  4. 安全提示:建议避免直接使用$wpdb执行SQL查询,优先使用会员插件(如MemberPress、Paid Memberships Pro)提供的官方API获取会员信息,降低SQL注入风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:20:05