🔍 IP归属地清理工具 v2
0. 当前数据库状态";
$totalBefore = $db->query("SELECT COUNT(*) as cnt FROM player_ip_locations")->fetchArray(SQLITE3_ASSOC)['cnt'] ?? 0;
echo "清理前总记录数: $totalBefore
";
// ★ 列出所有记录 + 逐条验证
echo "📋 全部记录逐条验证(使用统一校验函数 isValidIpLocationFormat)
";
echo "| IP | 位置 | 验证结果 | 删除原因 |
";
$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 "| $ip | ";
echo "" . htmlspecialchars($loc) . " | ";
echo "$funcStr | ";
echo "" . ($shouldDelete ? "$reason" : '-') . " | ";
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 "
";
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):
- 空值、短杠、双短杠、NULL
- 查询失败、查询中、内网IP
- 英文格式(China - xxx)
- 不完整的中文格式(中国 - -xxx)
- 无空格(缺少运营商分隔)
- 直辖市缺少"市"(如"北京 移动"→应为"北京市 移动")
- 非直辖市缺少城市后缀(如"湖北省 移动"→应为"湖北省武汉市 移动")
- 支持无后缀格式(如"湖北武汉 移通")