country($ip); $code = $record->country->isoCode ?? null; if (!is_string($code) || $code === '') { return null; } return strtoupper($code); } catch (AddressNotFoundException $e) { return null; } catch (\Throwable $e) { return null; } } /** * MMDB 绝对路径 */ public static function getDatabasePath(): string { return rtrim((string) ROOT_PATH, '/\\') . DIRECTORY_SEPARATOR . self::DB_FILENAME; } public static function isDatabaseAvailable(): bool { $path = self::getDatabasePath(); return is_file($path) && is_readable($path); } private static function bootstrapLibrary(): void { static $bootstrapped = false; if ($bootstrapped) { return; } $bootstrapped = true; $loader = ROOT_PATH . 'patches/third_party/load_geoip2.php'; if (is_file($loader)) { require_once $loader; } } private static function getReader(): Reader { if (self::$reader instanceof Reader) { return self::$reader; } if (!self::isDatabaseAvailable()) { throw new \RuntimeException('GeoLite2-Country.mmdb not readable at project root'); } self::$reader = new Reader(self::getDatabasePath()); return self::$reader; } }