最近在调整网站导航菜单的时候遇到了一个非常典型的 WordPress 故障:网站前台访问完全正常,所有页面打开都没问题,但只要进入后台「外观 → 菜单」页面,随便修改一个菜单项的文字,点击「保存菜单」按钮,页面就会长时间转圈加载,最后弹出 WordPress 的“本网站出现严重错误”白屏提示。更奇怪的是,只要点击浏览器返回按钮退出后台,整个网站一切恢复原样,没有任何功能异常。
一、问题排查的几个误区
最开始遇到这个问题的时候,第一反应是主题模板代码出了问题。
因为当时刚好在修改主题里的归档页面模板,里面用了硬编码的绝对路径引入文件:
include_once $_SERVER['DOCUMENT_ROOT'].'/wp-content/themes/aldehyde/inc/aboutme.php'
一开始判断是这种写法在WordPress后台AJAX保存菜单的环境下,服务器根目录变量不稳定,导致文件引入失败,抛出PHP致命错误,于是把所有路径换成了WordPress标准函数get_template_directory()。
但替换完代码之后,再去后台点保存菜单,故障依旧,还是会转圈报错,说明这个猜测并没有命中问题的根源。
二、绕开报错的临时方案:直接修改数据库改菜单文字
既然后台菜单页面的保存按钮会触发致命错误,完全不需要死磕这个页面,可以直接通过数据库修改菜单项文字,彻底绕开有问题的AJAX保存接口。
操作非常简单,打开phpMyAdmin进入网站数据库:
1. 先执行查询语句,定位到要修改的菜单项:
SELECT p.ID, p.post_title, pm.meta_value FROM wp_posts p LEFT JOIN wp_postmeta pm ON p.ID = pm.post_id AND pm.meta_key = '_menu_item_label' WHERE p.post_type = 'nav_menu_item' AND (p.post_title LIKE '%广告投放%' OR pm.meta_value LIKE '%广告投放%');
2. 执行完会查到对应的菜单项ID,这里查到的目标菜单项ID是1777,直接执行更新语句把文字改成想要的「关于遇见」:
UPDATE wp_posts SET post_title = '关于遇见' WHERE ID = 1777 AND post_type = 'nav_menu_item';
执行后提示“影响了1行”,说明数据库里的菜单文字已经修改完成。
这里要注意一个很多人不知道的细节:WordPress后台手动修改过的菜单自定义显示标签,是存在wp_postmeta表的_menu_item_label字段里的,不是直接存在wp_posts.post_title里;如果你的菜单项在后台单独设置过导航标签,就需要同时更新这个postmeta字段,不然前台显示的还是旧文字。
三、改完数据库前台还是旧文字?Redis缓存的坑
本来以为改完数据库,刷新前台就能看到新的菜单文字,结果用无痕浏览器打开网站,导航栏里依然显示旧的「广告投放」。
这时候才想起网站之前部署了 Redis 作为 WordPress 的对象缓存,同时还装了页面缓存插件。
WordPress开启Redis对象缓存之后,所有公共数据 —— 包括导航菜单、文章列表、系统设置 —— 都会直接缓存在Redis里,不会每次请求都读取数据库。你直接在数据库里改了数据,只要Redis里还存着旧的菜单缓存,前台就永远读不到你修改的新内容。
解决方法也很直接:
1. 清空Redis全部缓存,SSH终端执行命令:
redis-cli FLUSHALL
这条命令只会清空Redis里的缓存数据,不会删除网站的数据库和文件,WordPress会自动重新把新的数据库内容生成缓存,完全安全。
2. 再进入网站缓存插件后台,点击「清除所有缓存」。
清完这两层缓存之后,再打开前台网站,导航菜单立刻就显示修改后的「关于遇见」了,全程再也没有碰过那个会报错的后台菜单保存页面。
四、这次故障总结的几个避坑点
- 主题模板文件里,尽量不要硬编码服务器根目录这种超全局变量来引入文件,不同运行环境下这个变量的值不稳定,一定要用WordPress自带的
get_template_directory()函数来获取主题路径,前后台、AJAX环境都能正常工作。 - 遇到后台菜单保存报错的时候,不需要一直纠结后台页面为什么崩,可以直接用SQL语句修改数据库里的nav_menu_item记录,快速完成菜单文字的修改,不影响网站正常运行。
- 网站开启Redis对象缓存之后,任何直接在数据库里修改的内容,都必须手动清一次Redis缓存,不然前台永远显示旧的缓存数据,不会实时同步你修改的内容。
- 注意区分两类“菜单”:一类是WordPress全局导航菜单,存在数据库里;另一类是主题模板页面内部的tab标签文字,这种直接修改对应的主题PHP模板文件就可以,完全不需要进后台菜单页面修改,不要把两者混为一谈。
这次故障虽然小,但也是很多WordPress站长建站过程中经常会遇到的问题:前台正常、后台功能报错、改了数据库不生效,本质上就是模板环境兼容性和多层缓存的问题,顺着流程排查,不用死磕报错页面本身,就能快速解决。
