WordPress插件前台触发两次后台仅触发一次 访问计数翻倍问题
问题原因
- 统计逻辑未做请求过滤,浏览器预请求、favicon.ico请求、站点重定向都会触发两次代码执行,导致计数翻倍
- IP获取逻辑错误:
$_SERVER['SERVER_ADDR']是服务器自身IP而非访问用户IP,且对字符串类型的IP做intval()转换导致IP存储完全错误,IP匹配逻辑失效 - 插入新记录时未设置
visits字段初始值,若数据库未配置默认值也会导致统计异常
修复步骤
- 首先给数据库表添加唯一索引,避免同一天同一IP生成多条记录,执行SQL:
ALTER TABLE `wp_wps_user_visits` ADD UNIQUE INDEX `idx_ip_date` (`ip`, `date`);
注意将表前缀wp_替换为你实际的WordPress表前缀。
- 替换
front-end.php的代码,修复IP获取逻辑、添加执行锁避免同请求重复调用、用原子SQL语句避免竞态问题:
function wps_user_visits_count(){ // 静态执行锁,同一次请求内函数只会执行一次 static $executed = false; if ($executed) return; $executed = true; // 过滤非前台页面主请求 if (wp_doing_ajax() || wp_is_rest_endpoint() || is_robots() || is_404()) { return; } global $wpdb; $tp = $wpdb->prefix; $today = date('Y-m-d'); // 正确获取用户IP $ip = ''; if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0]; } else { $ip = $_SERVER['REMOTE_ADDR']; } $ip = sanitize_text_field($ip); // 原子SQL实现存在则更新、不存在则插入,无需先查后写 $wpdb->query($wpdb->prepare( "INSERT INTO `{$tp}wps_user_visits` (`ip`, `date`, `visits`) VALUES (%s, %s, 1) ON DUPLICATE KEY UPDATE `visits` = `visits` + 1", $ip, $today )); } add_action('wps_update_db','wps_user_visits_count');
- 若需要进一步降低异常计数,可以添加UA判断逻辑,过滤常见爬虫的UA标识。
内容的提问来源于stack exchange,提问作者Mohammad Afzali
相关产品推荐
相关产品推荐

