自定义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
相关产品推荐
相关产品推荐

