61 lines
1.6 KiB
PHP
61 lines
1.6 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace app\common\service;
|
||
|
||
/**
|
||
* 分流链接 IP 防护:开启时校验访客 IP 国家是否在链接投放国家列表内
|
||
*/
|
||
class SplitIpProtectService
|
||
{
|
||
/**
|
||
* 是否允许继续轮转跳转
|
||
*
|
||
* @param int|string $ipProtect 链接 ip_protect:0=关闭,1=开启
|
||
* @param string $countriesStorage 链接 countries 字段(ISO2 逗号分隔)
|
||
* @param string $clientIp 访客 IP
|
||
*/
|
||
public static function isAllowed($ipProtect, string $countriesStorage, string $clientIp): bool
|
||
{
|
||
if ((int) $ipProtect !== 1) {
|
||
return true;
|
||
}
|
||
|
||
$allowed = self::parseAllowedCountries($countriesStorage);
|
||
if ($allowed === []) {
|
||
return false;
|
||
}
|
||
|
||
if (!SplitGeoIpService::isDatabaseAvailable()) {
|
||
return false;
|
||
}
|
||
|
||
$visitorCountry = SplitGeoIpService::getCountryIso2($clientIp);
|
||
if ($visitorCountry === null || $visitorCountry === '') {
|
||
return false;
|
||
}
|
||
|
||
return in_array($visitorCountry, $allowed, true);
|
||
}
|
||
|
||
/**
|
||
* @return array<int, string> 大写 ISO2 列表
|
||
*/
|
||
public static function parseAllowedCountries(string $storage): array
|
||
{
|
||
if (trim($storage) === '') {
|
||
return [];
|
||
}
|
||
$result = [];
|
||
foreach (explode(',', $storage) as $code) {
|
||
$code = strtoupper(trim($code));
|
||
if ($code !== '' && !in_array($code, $result, true)) {
|
||
$result[] = $code;
|
||
}
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
}
|