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

自定义Nav Walker类PHP警告问题排查与修复咨询

问题描述

开发了一个自定义Nav Walker类,仅用于添加部分CSS类并替换部分菜单项的URL,菜单可正常显示,但出现大量PHP警告:

PHP Warning:  Attempt to read property "before" on null in /public_html/example.com/wp-includes/class-walker-nav-menu.php on line 273
PHP Warning:  Attempt to read property "link_before" on null in /public_html/example.com/wp-includes/class-walker-nav-menu.php on line 275
PHP Warning:  Attempt to read property "link_after" on null in /public_html/example.com/wp-includes/class-walker-nav-menu.php on line 275
PHP Warning:  Attempt to read property "after" on null in /public_html/example.com/wp-includes/class-walker-nav-menu.php on line 277
PHP Warning:  Attempt to read property "before" on null in /public_html/example.com/wp-includes/class-walker-nav-menu.php on line 273
PHP Warning:  Attempt to read property "link_before" on null in /public_html/example.com/wp-includes/class-walker-nav-menu.php on line 275
PHP Warning:  Attempt to read property "link_after" on null in /public_html/example.com/wp-includes/class-walker-nav-menu.php on line 275
PHP Warning:  Attempt to read property "after" on null in /public_html/example.com/wp-includes/class-walker-nav-menu.php on line 277

对应的自定义类代码如下:

class Navigation extends Walker_Nav_Menu {
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat( "\t", $depth );
        $output .= "\n$indent<ul class=\"menu submenu\">\n";
    }

    function start_el(&$output, $data_object, $depth = 0, $args = null, $current_object_id  = 0)
    {
        $f_menu = get_field('menu_item', 'option');
        $s_menu = get_field('menu_item_second', 'option');

        if ($data_object->title == $f_menu) {
            $url = get_field('outbreak_plan', 'option');
            $data_object->url = $url['url'];
        } else if ($data_object->title == $s_menu) {
            $url = get_field('covid_updates', 'option');
            $data_object->url = $url['url'];
        }
        parent::start_el($output, $data_object, $depth = 0, $args = null, $current_object_id  = 0);
    }
}

同服务器上其他站点使用该代码无警告,请问如何修复代码或屏蔽该文件的警告?


解决方案

一、修复代码(推荐)

警告的核心原因是调用parent::start_el()时,你手动传入了$args = null、固定值$depth = 0和$current_object_id = 0,而非传递当前函数接收到的原始参数。WordPress父类Walker_Nav_Menu需要通过$args对象读取before、link_before等属性,传入null直接触发了“读取null属性”的警告。

核心修复步骤

修改start_el方法的最后一行,直接传递原始参数,不要手动赋值:

parent::start_el($output, $data_object, $depth, $args, $current_object_id);

优化后的完整代码

同时优化字段查询逻辑,避免重复调用get_field,并增加空值判断防止ACF字段未配置时报错:

class Navigation extends Walker_Nav_Menu {
    // 缓存ACF字段值,减少重复数据库查询
    private static $f_menu = null;
    private static $s_menu = null;
    private static $outbreak_plan_url = null;
    private static $covid_updates_url = null;

    function __construct() {
        if (self::$f_menu === null) {
            self::$f_menu = get_field('menu_item', 'option');
            self::$s_menu = get_field('menu_item_second', 'option');
            
            // 空值判断,避免字段未设置时出现报错
            $outbreak_plan = get_field('outbreak_plan', 'option');
            self::$outbreak_plan_url = $outbreak_plan ? $outbreak_plan['url'] : '';
            
            $covid_updates = get_field('covid_updates', 'option');
            self::$covid_updates_url = $covid_updates ? $covid_updates['url'] : '';
        }
    }

    function start_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat( "\t", $depth );
        $output .= "\n$indent<ul class=\"menu submenu\">\n";
    }

    function start_el(&$output, $data_object, $depth = 0, $args = null, $current_object_id  = 0)
    {
        if ($data_object->title == self::$f_menu && self::$outbreak_plan_url) {
            $data_object->url = self::$outbreak_plan_url;
        } else if ($data_object->title == self::$s_menu && self::$covid_updates_url) {
            $data_object->url = self::$covid_updates_url;
        }
        
        // 传递原始参数给父类方法
        parent::start_el($output, $data_object, $depth, $args, $current_object_id);
    }
}

二、屏蔽警告(不推荐)

若临时需要掩盖警告,可在主题functions.php中添加以下代码,但这只是治标不治本的方案:

// 仅屏蔽指定文件的PHP警告
add_action('init', function() {
    $target_file = ABSPATH . 'wp-includes/class-walker-nav-menu.php';
    if (file_exists($target_file)) {
        $original_error_level = error_reporting();
        error_reporting($original_error_level & ~E_WARNING);
        include_once($target_file);
        error_reporting($original_error_level);
    }
});

也可修改PHP配置(不推荐,会影响整个站点的错误提示):
在php.ini中添加或修改:

error_reporting = E_ALL & ~E_WARNING

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:57:28