61 lines
1.7 KiB
PHP
61 lines
1.7 KiB
PHP
<?php
|
|
/**
|
|
* 将 GeoIP / API 返回的国家值统一为 ISO 3166-1 alpha-2(两位大写国家码)。
|
|
*/
|
|
class CountryCodeNormalizer
|
|
{
|
|
/** @var array{names:array<string,string>,alpha3:array<string,string>}|null */
|
|
private static $maps = null;
|
|
|
|
/**
|
|
* @param mixed $value ISO2、ISO3 或英文国名
|
|
* @return string|null 两位国家码;无法识别时 null
|
|
*/
|
|
public static function toAlpha2($value)
|
|
{
|
|
$value = trim((string) $value);
|
|
if ($value === '') {
|
|
return null;
|
|
}
|
|
|
|
$upper = strtoupper($value);
|
|
if (preg_match('/^[A-Z]{2}$/', $upper)) {
|
|
return $upper;
|
|
}
|
|
|
|
$maps = self::maps();
|
|
if (preg_match('/^[A-Z]{3}$/', $upper) && isset($maps['alpha3'][$upper])) {
|
|
return $maps['alpha3'][$upper];
|
|
}
|
|
|
|
$nameKey = self::nameKey($value);
|
|
if (isset($maps['names'][$nameKey])) {
|
|
return $maps['names'][$nameKey];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @return array{names:array<string,string>,alpha3:array<string,string>}
|
|
*/
|
|
private static function maps()
|
|
{
|
|
if (self::$maps === null) {
|
|
$file = __DIR__ . '/iso3166_maps.php';
|
|
$data = is_file($file) ? require $file : ['names' => [], 'alpha3' => []];
|
|
self::$maps = [
|
|
'names' => isset($data['names']) && is_array($data['names']) ? $data['names'] : [],
|
|
'alpha3' => isset($data['alpha3']) && is_array($data['alpha3']) ? $data['alpha3'] : [],
|
|
];
|
|
}
|
|
return self::$maps;
|
|
}
|
|
|
|
private static function nameKey($name)
|
|
{
|
|
$name = preg_replace('/\s+/u', ' ', trim((string) $name));
|
|
return strtoupper($name);
|
|
}
|
|
}
|