🔍 IP归属地清理工具 v2

0. 当前数据库状态"; $totalBefore = $db->query("SELECT COUNT(*) as cnt FROM player_ip_locations")->fetchArray(SQLITE3_ASSOC)['cnt'] ?? 0; echo "

清理前总记录数: $totalBefore

"; // ★ 列出所有记录 + 逐条验证 echo "

📋 全部记录逐条验证(使用统一校验函数 isValidIpLocationFormat)

"; echo ""; $allStmt = $db->query("SELECT ip_address, location FROM player_ip_locations ORDER BY ip_address"); $records = []; while ($row = $allStmt->fetchArray(SQLITE3_ASSOC)) { $records[] = $row; } $deletedCount = 0; $checkedCount = 0; foreach ($records as $row) { $ip = $row['ip_address']; $loc = $row['location']; $checkedCount++; // ★ 直接使用统一校验函数 $isValid = isValidIpLocationFormat($loc); // 判断删除原因(用于显示) $reason = ''; if (!$isValid) { if ($loc === '' || $loc === null || $loc === 'NULL' || $loc === '-' || $loc === '--') { $reason = "空值/短杠"; } elseif ($loc === '查询失败' || $loc === '查询中' || $loc === '内网IP') { $reason = "特殊标记"; } elseif (stripos($loc, 'China') === 0) { $reason = "英文格式"; } elseif (strpos($loc, '中国 - -') === 0 || strpos($loc, '中国 - -') === 0) { $reason = "不完整中文格式"; } elseif (preg_match('/^中国\s*$/u', $loc) || preg_match('/^中国\s+[^\s省市区州盟]+$/u', $loc)) { $reason = "不完整中文格式"; } elseif (strpos($loc, ' ') === false) { $reason = "无空格"; } else { $reason = "省市格式不符合"; } } $shouldDelete = !$isValid; $funcStr = $isValid ? '✅' : '❌'; $rowClass = $shouldDelete ? 'row-invalid' : 'row-valid'; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; if ($shouldDelete) { $delStmt = $db->prepare("DELETE FROM player_ip_locations WHERE ip_address = :ip"); $delStmt->bindValue(':ip', $ip, SQLITE3_TEXT); $delStmt->execute(); $deletedCount++; } } echo "
IP位置验证结果删除原因
$ip" . htmlspecialchars($loc) . "$funcStr" . ($shouldDelete ? "$reason" : '-') . "
"; echo "

检查了 $checkedCount 条记录

"; if ($deletedCount > 0) { echo "

✅ 删除 $deletedCount 条无效记录

"; } else { echo "

无无效记录

"; } // 统计 $totalAfter = $db->query("SELECT COUNT(*) as cnt FROM player_ip_locations")->fetchArray(SQLITE3_ASSOC)['cnt'] ?? 0; echo "

清理前: $totalBefore → 清理后: $totalAfter

"; // 需要重新查询的IP(过滤掉短杠和空值) echo "

6. 需要重新查询的IP(player_ip_changes 中有但 player_ip_locations 中没有的)

"; $needQuery = $db->query(" SELECT DISTINCT pic.new_ip FROM player_ip_changes pic LEFT JOIN player_ip_locations pil ON pic.new_ip = pil.ip_address WHERE pil.ip_address IS NULL AND pic.new_ip IS NOT NULL AND pic.new_ip != '' AND pic.new_ip NOT IN ('-', '--') AND pic.new_ip LIKE '%.%' ORDER BY pic.new_ip LIMIT 50 "); $needQueryList = []; while ($row = $needQuery->fetchArray(SQLITE3_ASSOC)) { $needQueryList[] = $row['new_ip']; } echo "

找到 " . count($needQueryList) . " 个需要查询的IP

"; if (!empty($needQueryList)) { echo "
";
        foreach ($needQueryList as $ip) {
            echo $ip . "\n";
        }
        echo "
"; } // 额外:player_ip_locations 中存储了短杠位置的记录 echo "

7. 数据库中存储了短杠位置的记录

"; $dashLocQuery = $db->query("SELECT ip_address, location FROM player_ip_locations WHERE location IN ('-', '--', '') OR location IS NULL"); $dashLocCount = 0; while ($row = $dashLocQuery->fetchArray(SQLITE3_ASSOC)) { echo "

" . $row['ip_address'] . " => " . htmlspecialchars($row['location'] ?? 'NULL') . "

"; $dashLocCount++; } if ($dashLocCount === 0) { echo "

无短杠位置记录

"; } else { echo "

找到 $dashLocCount 条短杠位置记录,将清理

"; $db->exec("DELETE FROM player_ip_locations WHERE location IN ('-', '--', '') OR location IS NULL"); echo "

已清理短杠位置记录

"; } echo "

✅ 清理完成!请刷新用户管理页面查看效果。

"; } catch (Exception $e) { echo "

错误: " . $e->getMessage() . "

"; echo "
" . $e->getTraceAsString() . "
"; } ?>

💡 清理规则(使用统一校验函数 isValidIpLocationFormat):

  1. 空值、短杠、双短杠、NULL
  2. 查询失败、查询中、内网IP
  3. 英文格式(China - xxx)
  4. 不完整的中文格式(中国 - -xxx)
  5. 无空格(缺少运营商分隔)
  6. 直辖市缺少"市"(如"北京 移动"→应为"北京市 移动")
  7. 非直辖市缺少城市后缀(如"湖北省 移动"→应为"湖北省武汉市 移动")
  8. 支持无后缀格式(如"湖北武汉 移通")