摘要
在某些情况访问使用Argon主题的Wordpress站点,网页会有低概率出现 Warning Undefined array key "HTTP_USER_AGENT" 这个报错,这篇文章面向各位网站管理员,介绍如何通过修改主题源码的方式根治这个报错。
问题具体表现
在未登录状态下访问了启用Argon主题的Wordpress站点,有概率会发现页首下面有一个报错(不同的布局下位置可能不一样,但是都在页面靠上的部分),如图1中红框圈出的部分。并且这个报错在登录网站或在清除网站缓存(如果网站使用了WP Super Cache或者类似的缓存插件,此处是指清理了服务器端的网页预编译缓存,而不是浏览器的本地缓存)后又会消失。

问题出现的原因
问题归根究底是因为Argon主题并没有对HTTP_USER_AGENT这值是否存在进行检查。详细来说,User-Agent是用户程序(如浏览器)用于标识自身身份的字段[1],PHP会给每个请求填充一个$_SERVER数组作为全局变量 [2],Argon主题的代码则可以对这个数组中的元素进行获取以及处理,而HTTP_USER_AGENT是作为其中的一个元素的。但是,在一些情况下,这个元素是可以不存在的(比如说网上的一些探测工具不会发送USER-AGENT信息),而Argon的代码对HTTP_USER_AGENT不存的情况并没有妥善的处理,便会在本次请求触发Warning Undefined array key "HTTP_USER_AGENT"这个错误。注意,这个只会在PHP 8中触发为Warning,在PHP 7中触发这种情况触发的是E_NOTICE,而E_NOTICE在默认情况下不会被显示出来[3]。而如果网站使用如Wordpress缓存插件如WP Super Cache,并且将这个错误的响应缓存了,那么就会导致正常访客的页面也出现这个报错。
结合实际例子来说,我们打一个比方,站点A使用了wordpress并启用了Argon主题、WP Super Cache,并且设定了对访问的页面进行缓存。而在某一个时间点,页面a还没有被WP Super Cache插件进行预编译缓存。此时,网上一个扫描器访问了这个页面a,这个扫描器故意不发送User-Agent,以避免被部分WAF的规则匹配中。此时PHP传递给Argon的$_SERVER数组中是没有HTTP_USER_AGENT这个值,导致返回的界面中出现了Warning Undefined array key "HTTP_USER_AGENT" 报错。而且由于请求完成,带有这个报错的页面被返回给扫描器,并且返回的内容被WP Super Cache插件进行预缓存。别的正常访客访问页面a的时候,WP Super Cache发现页面a已经被缓存了,便将刚刚缓存的html代码返回给正常访客,但是刚刚返回的html代码是有报错信息的,所以导致正常用户访问页面a是会看到页首有这个报错信息。而管理员发现了这个问题,在登录状态下管理员访问页面a却看不到这个报错信息,因为管理员是登录状态,而WP Super Cache在默认配置下,并不会将缓存的结果返回给登录了的用户。虽然出现这个报错要求的情况比较苛刻,但是在实际应用中确实会发生这个的状况,尤其是随着网站访客的增加,各种扫描器的访问数量也会增加,就越有这个可能出现这个问题,(我的网站已经出现两次这个报错)。如图2所示,下图就是有不发送User-Agent信息的扫描器请求我网站出现这个报错的日志,我将具体的导致报错的条目用红框圈出来了。

这里我有一个猜测,Argon主题的最后一次更新(截止到发布本篇文章的时候,是1.3.5),时间为2022年3月18号,而2022年的时候,大部分人还使用的是PHP7[4],而这个报错就如前文所说到的,不会在PHP7版本下出现,作者当时没有注意到这个PHP8的改变,所以才会有这个问题。
测试站点是否有这个问题
如果您想测试下您的站点是否有这个问题,可以使用curl程序。在清除掉所有的缓存后,构造curl请求参数,让其使用UserAgent参数为空的请求来请求下自己的站点,对应的Curl命令如下:
curl.exe -H "User-Agent:" https://www.q2019.com
将Curl输出的结果复制,并保存为html,双击保存的文件,在浏览器中打开,看下界面是否有 Warning Undefined array key "HTTP_USER_AGENT"这个报错。如果有,则请移步下一步的修复。
当然,您也可以通过PHP的错误日志,来查看网站是否曾经出过这个问题。
问题解决方案
主要的思路就是修改Argon主题的源码,如果HTTP_USER_AGENT这个不存在的时候,便设定为一个空的字串符用来占位,而不是抛出一个错误。我们可以使用Wordpress自带的主题编辑器或者登录服务器用别的编辑器来对源码进行修改。
在此要特别说明:本文的修改是基于本文发文时的Argon的最新版本(V1.3.5,于2022年3月18日发布),如果Argon后续有更新,需要修改的代码的行数可能会变化。并且应用我提供的方案前,请务必做好服务器备份,并做好评估与测试!最好使用子主题的方式对代码进行修改。
使用Wordpress自带的主题编辑器
前往wordpress后台,点击左侧栏目外观,点击后点击新出现的主题文件编辑器选项,在跳转后的页面中点击右侧主题文件列表中的主题页眉选项,要点击的按钮我已经在图3中用红框框圈出了

打开后将代码中的第45行处的代码,将下面的代码块
$htmlclasses .= get_option('argon_article_header_style', 'article-header-style-default') . ' ';
if(strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') !== false && strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome') === false){
$htmlclasses .= ' using-safari';
}
替换为下面的代码即可
$htmlclasses .= get_option('argon_article_header_style', 'article-header-style-default') . ' ';
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
if (strpos($ua, 'Safari') !== false && strpos($ua, 'Chrome') === false){
$htmlclasses .= ' using-safari';
}
使用别的编辑器对源码进行修改
部分情况下我们可能无法使用wordpress自带的主题编辑器编辑主题文件(比如,部署了雷池WAF会导致编辑主题文件的请求被拦截),这时候我们可以使用别的编辑器对文件进行编辑,如服务器有宝塔的话可以用宝塔的在线文件管理模块,或者登录服务器ssh终端后使用vim进行编辑。
我们要编辑的文件的地址是
你的站点根目录/wp-content/themes/argon/header.php
如果使用宝塔建站的话,文件路径是下面的样子的
/www/wwwroot/站点名称/wp-content/themes/argon/header.php
具体的编辑内容跟使用wordpress编辑器的是一样的