ip() when the request did not come through CDN. * Do not trust JSON/query `ip` or a client-prefixed X-Forwarded-For hop. */ final class VisitorIp { public static function fromRequest(Request $request): string { foreach (['CF-Connecting-IP', 'True-Client-IP'] as $header) { $ip = self::normalize($request->headers->get($header)); if ($ip !== '') { return $ip; } } $fallback = self::normalize((string) $request->ip()); return $fallback !== '' ? $fallback : substr((string) $request->ip(), 0, 64); } public static function normalize(?string $raw): string { $raw = trim((string) $raw); if ($raw === '') { return ''; } if (str_contains($raw, ',')) { $raw = trim(explode(',', $raw, 2)[0]); } if (filter_var($raw, FILTER_VALIDATE_IP) === false) { return ''; } $norm = PageVisit::normalizeIp($raw); return $norm !== '' ? substr($norm, 0, 64) : ''; } }