|
|
@@ -21,6 +21,10 @@ class IP
|
|
|
{
|
|
|
private static bool $is_ipv4;
|
|
|
|
|
|
+ private static string $ip;
|
|
|
+
|
|
|
+ private static PendingRequest $basicRequest;
|
|
|
+
|
|
|
public static function getClientIP(): ?string
|
|
|
{ // 获取访客真实IP
|
|
|
return request()?->ip();
|
|
|
@@ -38,8 +42,6 @@ class IP
|
|
|
return $info;
|
|
|
}
|
|
|
|
|
|
- $ret = null;
|
|
|
- $source = 0;
|
|
|
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
|
|
self::$is_ipv4 = true;
|
|
|
} elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
|
|
@@ -47,58 +49,17 @@ class IP
|
|
|
} else {
|
|
|
return false;
|
|
|
}
|
|
|
+ self::$ip = $ip;
|
|
|
+ self::$basicRequest = Http::timeout(10)->withOptions(['http_errors' => false])->withUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36');
|
|
|
|
|
|
if (app()->getLocale() === 'zh_CN') {
|
|
|
if (self::$is_ipv4) {
|
|
|
- while ($source <= 11 && ($ret === null || (is_array($ret) && empty(array_filter($ret))))) { // 中文ipv6
|
|
|
- $ret = match ($source) {
|
|
|
- 0 => self::ipApi($ip),
|
|
|
- 1 => self::Baidu($ip),
|
|
|
- 2 => self::baiduBce($ip),
|
|
|
- 3 => self::ipGeoLocation($ip),
|
|
|
- 4 => self::TaoBao($ip),
|
|
|
- 5 => self::speedtest($ip),
|
|
|
- 6 => self::TenAPI($ip),
|
|
|
- 7 => self::fkcoder($ip),
|
|
|
- 8 => self::juHe($ip),
|
|
|
- 9 => self::ipjiance($ip),
|
|
|
- 10 => self::ip2Region($ip),
|
|
|
- 11 => self::IPIP($ip),
|
|
|
- //10 => self::userAgentInfo($ip), // 无法查外网的ip
|
|
|
- };
|
|
|
- $source++;
|
|
|
- }
|
|
|
+ $ret = self::IPLookup(['ipApi', 'Baidu', 'baiduBce', 'ipw', 'ipGeoLocation', 'TaoBao', 'speedtest', 'bjjii', 'TenAPI', 'fkcoder', 'vore', 'juHe', 'vvhan', 'ipjiance', 'ip2Region', 'IPIP']);
|
|
|
} else {
|
|
|
- while ($source <= 5 && ($ret === null || (is_array($ret) && empty(array_filter($ret))))) {
|
|
|
- $ret = match ($source) {
|
|
|
- 0 => self::ipApi($ip),
|
|
|
- 1 => self::baiduBce($ip),
|
|
|
- 2 => self::Baidu($ip),
|
|
|
- 3 => self::ipGeoLocation($ip),
|
|
|
- 4 => self::TenAPI($ip),
|
|
|
- 5 => self::ip2Region($ip),
|
|
|
- };
|
|
|
- $source++;
|
|
|
- }
|
|
|
+ $ret = self::IPLookup(['ipApi', 'Baidu', 'baiduBce', 'ipw', 'ipGeoLocation', 'TenAPI', 'vore', 'ip2Region']);
|
|
|
}
|
|
|
} else {
|
|
|
- while ($source <= 11 && ($ret === null || (is_array($ret) && empty(array_filter($ret))))) { // 英文
|
|
|
- $ret = match ($source) {
|
|
|
- 0 => self::ipApi($ip),
|
|
|
- 1 => self::IPSB($ip),
|
|
|
- 2 => self::ipinfo($ip),
|
|
|
- 3 => self::ip234($ip),
|
|
|
- 4 => self::ipGeoLocation($ip),
|
|
|
- 5 => self::dbIP($ip),
|
|
|
- 6 => self::IP2Online($ip),
|
|
|
- 7 => self::ipdata($ip),
|
|
|
- 8 => self::ipApiCo($ip),
|
|
|
- 9 => self::ip2Location($ip),
|
|
|
- 10 => self::GeoIP2($ip),
|
|
|
- 11 => self::ipApiCom($ip),
|
|
|
- };
|
|
|
- $source++;
|
|
|
- }
|
|
|
+ $ret = self::IPLookup(['ipApi', 'IPSB', 'ipinfo', 'ip234', 'ipGeoLocation', 'dbIP', 'IP2Online', 'ipdata', 'ipApiCo', 'ip2Location', 'GeoIP2', 'ipApiCom']);
|
|
|
}
|
|
|
|
|
|
if ($ret !== null) {
|
|
|
@@ -109,16 +70,68 @@ class IP
|
|
|
return $ret;
|
|
|
}
|
|
|
|
|
|
+ private static function IPLookup(array $checkers): ?array
|
|
|
+ {
|
|
|
+ foreach ($checkers as $checker) {
|
|
|
+ try {
|
|
|
+ $result = self::callApi($checker);
|
|
|
+ if (is_array($result) && ! empty(array_filter($result))) {
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+ } catch (Exception $e) {
|
|
|
+ Log::error("[$checker] IP信息获取报错: ".$e->getMessage());
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static function callApi(string $checker): ?array
|
|
|
+ {
|
|
|
+ $ip = self::$ip;
|
|
|
+
|
|
|
+ return match ($checker) {
|
|
|
+ 'ipApi' => self::ipApi($ip),
|
|
|
+ 'Baidu' => self::Baidu($ip),
|
|
|
+ 'baiduBce' => self::baiduBce($ip),
|
|
|
+ 'ipGeoLocation' => self::ipGeoLocation($ip),
|
|
|
+ 'TaoBao' => self::TaoBao($ip),
|
|
|
+ 'speedtest' => self::speedtest($ip),
|
|
|
+ 'TenAPI' => self::TenAPI($ip),
|
|
|
+ 'fkcoder' => self::fkcoder($ip),
|
|
|
+ 'juHe' => self::juHe($ip),
|
|
|
+ 'ip2Region' => self::ip2Region($ip),
|
|
|
+ 'IPIP' => self::IPIP($ip),
|
|
|
+ 'ipjiance' => self::ipjiance($ip),
|
|
|
+ 'IPSB' => self::IPSB($ip),
|
|
|
+ 'ipinfo' => self::ipinfo($ip),
|
|
|
+ 'ip234' => self::ip234($ip),
|
|
|
+ 'dbIP' => self::dbIP($ip),
|
|
|
+ 'IP2Online' => self::IP2Online($ip),
|
|
|
+ 'ipdata' => self::ipdata($ip),
|
|
|
+ 'ipApiCo' => self::ipApiCo($ip),
|
|
|
+ 'ip2Location' => self::ip2Location($ip),
|
|
|
+ 'GeoIP2' => self::GeoIP2($ip),
|
|
|
+ 'ipApiCom' => self::ipApiCom($ip),
|
|
|
+ 'vore' => self::vore($ip),
|
|
|
+ 'vvan' => self::vvhan($ip),
|
|
|
+ 'ipw' => self::ipw($ip),
|
|
|
+ 'bjjii' => self::bjjii($ip),
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
private static function ipApi(string $ip): ?array
|
|
|
{ // 开发依据: https://ip-api.com/docs/api:json
|
|
|
$key = config('services.ip.ip-api_key');
|
|
|
if ($key) {
|
|
|
- $response = self::setBasicHttp()->withHeaders(['Origin' => 'https://members.ip-api.com'])->acceptJson()->get("https://pro.ip-api.com/json/$ip?fields=49881&key=$key&lang=".str_replace('_', '-', app()->getLocale()));
|
|
|
+ $response = self::$basicRequest->withHeaders(['Origin' => 'https://members.ip-api.com'])->acceptJson()->get("https://pro.ip-api.com/json/$ip?fields=49881&key=$key&lang=".str_replace('_', '-', app()->getLocale()));
|
|
|
if (! $response->ok()) {
|
|
|
- $response = self::setBasicHttp()->acceptJson()->get("http://ip-api.com/json/$ip?fields=49881&lang=".str_replace('_', '-', app()->getLocale()));
|
|
|
+ $response = self::$basicRequest->acceptJson()->get("http://ip-api.com/json/$ip?fields=49881&lang=".str_replace('_', '-', app()->getLocale()));
|
|
|
}
|
|
|
} else {
|
|
|
- $response = self::setBasicHttp()->acceptJson()->get("http://ip-api.com/json/$ip?fields=49881&lang=".str_replace('_', '-', app()->getLocale()));
|
|
|
+ $response = self::$basicRequest->acceptJson()->get("http://ip-api.com/json/$ip?fields=49881&lang=".str_replace('_', '-', app()->getLocale()));
|
|
|
}
|
|
|
|
|
|
if ($response->ok()) {
|
|
|
@@ -143,18 +156,12 @@ class IP
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- private static function setBasicHttp(): PendingRequest
|
|
|
- {
|
|
|
- return Http::timeout(10)->withOptions(['http_errors' => false])->withUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36');
|
|
|
- }
|
|
|
-
|
|
|
private static function Baidu(string $ip): ?array
|
|
|
{// 通过api.map.baidu.com查询IP地址的详细信息
|
|
|
$key = config('services.ip.baidu_ak');
|
|
|
if ($key) {
|
|
|
// 依据 http://lbsyun.baidu.com/index.php?title=webapi/ip-api 开发
|
|
|
- $response = self::setBasicHttp()->get("https://api.map.baidu.com/location/ip?ak=$key&ip=$ip&coor=gcj02");
|
|
|
-
|
|
|
+ $response = self::$basicRequest->get("https://api.map.baidu.com/location/ip?ak=$key&ip=$ip&coor=gcj02");
|
|
|
if ($response->ok()) {
|
|
|
$message = $response->json();
|
|
|
if ($message['status'] === 0) {
|
|
|
@@ -187,7 +194,7 @@ class IP
|
|
|
} else {
|
|
|
$url = "https://qifu-api.baidubce.com/ip/geo/v1/ipv6/district?ip=$ip";
|
|
|
}
|
|
|
- $response = self::setBasicHttp()->get($url);
|
|
|
+ $response = self::$basicRequest->get($url);
|
|
|
$data = $response->json();
|
|
|
if ($response->ok()) {
|
|
|
if ($data['code'] === 'Success' && $ip === $data['ip']) {
|
|
|
@@ -212,7 +219,7 @@ class IP
|
|
|
|
|
|
private static function ipGeoLocation(string $ip): ?array
|
|
|
{ // 开发依据: https://ipgeolocation.io/documentation.html
|
|
|
- $response = self::setBasicHttp()->withHeaders(['Origin' => 'https://ipgeolocation.io'])
|
|
|
+ $response = self::$basicRequest->withHeaders(['Origin' => 'https://ipgeolocation.io'])
|
|
|
->get("https://api.ipgeolocation.io/ipgeo?ip=$ip&fields=country_name,state_prov,district,city,isp,latitude,longitude&lang=".config('common.language.'.app()->getLocale().'.1'));
|
|
|
if ($response->ok()) {
|
|
|
$data = $response->json();
|
|
|
@@ -233,7 +240,7 @@ class IP
|
|
|
|
|
|
private static function TaoBao(string $ip): ?array
|
|
|
{ // 通过ip.taobao.com查询IP地址的详细信息 依据 https://ip.taobao.com/instructions 开发
|
|
|
- $response = self::setBasicHttp()->retry(2)->post("https://ip.taobao.com/outGetIpInfo?ip=$ip&accessKey=alibaba-inc");
|
|
|
+ $response = self::$basicRequest->retry(2)->post("https://ip.taobao.com/outGetIpInfo?ip=$ip&accessKey=alibaba-inc");
|
|
|
|
|
|
$message = $response->json();
|
|
|
if ($response->ok()) {
|
|
|
@@ -258,7 +265,7 @@ class IP
|
|
|
|
|
|
private static function speedtest(string $ip): ?array
|
|
|
{
|
|
|
- $response = self::setBasicHttp()->get("https://forge.speedtest.cn/api/location/info?ip=$ip");
|
|
|
+ $response = self::$basicRequest->get("https://forge.speedtest.cn/api/location/info?ip=$ip");
|
|
|
$data = $response->json();
|
|
|
if ($response->ok()) {
|
|
|
if ($data['ip'] === $ip) {
|
|
|
@@ -283,7 +290,7 @@ class IP
|
|
|
|
|
|
private static function TenAPI(string $ip): ?array
|
|
|
{ // 开发依据: https://docs.tenapi.cn/utility/getip.html
|
|
|
- $response = self::setBasicHttp()->asForm()->post('https://tenapi.cn/v2/getip', ['ip' => $ip]);
|
|
|
+ $response = self::$basicRequest->asForm()->post('https://tenapi.cn/v2/getip', ['ip' => $ip]);
|
|
|
if ($response->ok()) {
|
|
|
$data = $response->json();
|
|
|
|
|
|
@@ -293,7 +300,7 @@ class IP
|
|
|
'region' => $data['data']['province'],
|
|
|
'city' => $data['data']['city'],
|
|
|
'isp' => $data['data']['isp'],
|
|
|
- 'area' => '',
|
|
|
+ 'area' => null,
|
|
|
];
|
|
|
}
|
|
|
}
|
|
|
@@ -303,7 +310,7 @@ class IP
|
|
|
|
|
|
private static function fkcoder(string $ip): ?array
|
|
|
{ // 开发依据: https://www.fkcoder.com/
|
|
|
- $response = self::setBasicHttp()->acceptJson()->get("https://www.fkcoder.com/ip?ip=$ip");
|
|
|
+ $response = self::$basicRequest->acceptJson()->get("https://www.fkcoder.com/ip?ip=$ip");
|
|
|
if ($response->ok()) {
|
|
|
$data = $response->json();
|
|
|
|
|
|
@@ -321,7 +328,7 @@ class IP
|
|
|
|
|
|
private static function juHe(string $ip): ?array
|
|
|
{ // 开发依据: https://www.juhe.cn/docs/api/id/1
|
|
|
- $response = self::setBasicHttp()->asForm()->post('https://apis.juhe.cn/ip/Example/query.php', ['IP' => $ip]);
|
|
|
+ $response = self::$basicRequest->asForm()->post('https://apis.juhe.cn/ip/Example/query.php', ['IP' => $ip]);
|
|
|
if ($response->ok()) {
|
|
|
$data = $response->json();
|
|
|
if ($data['resultcode'] === '200' && $data['error_code'] === 0) {
|
|
|
@@ -378,16 +385,16 @@ class IP
|
|
|
|
|
|
private static function ipjiance(string $ip): ?array
|
|
|
{
|
|
|
- $response = self::setBasicHttp()->get("https://www.ipjiance.com/api/geoip/report?ip=$ip");
|
|
|
+ $response = self::$basicRequest->get("https://www.ipjiance.com/api/geoip/report?ip=$ip");
|
|
|
$data = $response->json();
|
|
|
if ($response->ok()) {
|
|
|
if ($data['code'] === 1) {
|
|
|
return [
|
|
|
'country' => $data['data']['country'],
|
|
|
- 'region' => '',
|
|
|
+ 'region' => null,
|
|
|
'city' => $data['data']['city'],
|
|
|
'isp' => $data['data']['isp'],
|
|
|
- 'area' => '',
|
|
|
+ 'area' => null,
|
|
|
'latitude' => $data['data']['latitude'],
|
|
|
'longitude' => $data['data']['longitude'],
|
|
|
];
|
|
|
@@ -404,7 +411,7 @@ class IP
|
|
|
private static function IPSB(string $ip): ?array
|
|
|
{ // 通过api.ip.sb查询IP地址的详细信息
|
|
|
try {
|
|
|
- $response = self::setBasicHttp()->post("https://api.ip.sb/geoip/$ip");
|
|
|
+ $response = self::$basicRequest->post("https://api.ip.sb/geoip/$ip");
|
|
|
|
|
|
if ($response->ok()) {
|
|
|
$data = $response->json();
|
|
|
@@ -428,9 +435,9 @@ class IP
|
|
|
{ // 开发依据: https://ipinfo.io/account/home
|
|
|
$key = config('services.ip.ipinfo_token');
|
|
|
if ($key) {
|
|
|
- $response = self::setBasicHttp()->acceptJson()->get("https://ipinfo.io/$ip?token=$key");
|
|
|
+ $response = self::$basicRequest->acceptJson()->get("https://ipinfo.io/$ip?token=$key");
|
|
|
} else {
|
|
|
- $response = self::setBasicHttp()->acceptJson()->withHeaders(['Referer' => 'https://ipinfo.io/'])->get("https://ipinfo.io/widget/demo/$ip");
|
|
|
+ $response = self::$basicRequest->acceptJson()->withHeaders(['Referer' => 'https://ipinfo.io/'])->get("https://ipinfo.io/widget/demo/$ip");
|
|
|
}
|
|
|
|
|
|
if ($response->ok()) {
|
|
|
@@ -454,7 +461,7 @@ class IP
|
|
|
|
|
|
private static function ip234(string $ip): ?array
|
|
|
{
|
|
|
- $response = self::setBasicHttp()->get("https://ip234.in/search_ip?ip=$ip");
|
|
|
+ $response = self::$basicRequest->get("https://ip234.in/search_ip?ip=$ip");
|
|
|
$data = $response->json();
|
|
|
if ($response->ok()) {
|
|
|
if ($data['code'] === 0) {
|
|
|
@@ -463,7 +470,7 @@ class IP
|
|
|
'region' => $data['data']['region'],
|
|
|
'city' => $data['data']['city'],
|
|
|
'isp' => $data['data']['organization'],
|
|
|
- 'area' => '',
|
|
|
+ 'area' => null,
|
|
|
'latitude' => $data['data']['latitude'],
|
|
|
'longitude' => $data['data']['longitude'],
|
|
|
];
|
|
|
@@ -479,7 +486,7 @@ class IP
|
|
|
|
|
|
private static function dbIP(string $ip): ?array
|
|
|
{ // 开发依据: https://db-ip.com/api/doc.php
|
|
|
- $response = self::setBasicHttp()->acceptJson()->get("https://api.db-ip.com/v2/free/$ip");
|
|
|
+ $response = self::$basicRequest->acceptJson()->get("https://api.db-ip.com/v2/free/$ip");
|
|
|
if ($response->ok()) {
|
|
|
$data = $response->json();
|
|
|
|
|
|
@@ -499,7 +506,7 @@ class IP
|
|
|
{ // 开发依据: https://www.ip2location.io/ip2location-documentation
|
|
|
$key = config('services.ip.IP2Location_key');
|
|
|
if ($key) {
|
|
|
- $response = self::setBasicHttp()->acceptJson()->get("https://api.ip2location.io/?key=$key&ip=$ip");
|
|
|
+ $response = self::$basicRequest->acceptJson()->get("https://api.ip2location.io/?key=$key&ip=$ip");
|
|
|
if ($response->ok()) {
|
|
|
$data = $response->json();
|
|
|
|
|
|
@@ -522,7 +529,7 @@ class IP
|
|
|
{ // 开发依据: https://docs.ipdata.co/docs
|
|
|
$key = config('services.ip.ipdata_key');
|
|
|
if ($key) {
|
|
|
- $response = self::setBasicHttp()->get("https://api.ipdata.co/$ip?api-key=$key&fields=ip,city,region,country_name,latitude,longitude,asn");
|
|
|
+ $response = self::$basicRequest->get("https://api.ipdata.co/$ip?api-key=$key&fields=ip,city,region,country_name,latitude,longitude,asn");
|
|
|
if ($response->ok()) {
|
|
|
$data = $response->json();
|
|
|
|
|
|
@@ -543,7 +550,7 @@ class IP
|
|
|
|
|
|
private static function ipApiCo(string $ip): ?array
|
|
|
{ // 开发依据: https://ipapi.co/api/
|
|
|
- $response = self::setBasicHttp()->get("https://ipapi.co/$ip/json/");
|
|
|
+ $response = self::$basicRequest->get("https://ipapi.co/$ip/json/");
|
|
|
if ($response->ok()) {
|
|
|
$data = $response->json();
|
|
|
|
|
|
@@ -608,7 +615,7 @@ class IP
|
|
|
|
|
|
private static function ipApiCom(string $ip): ?array
|
|
|
{ // 开发依据: https://docs.ipdata.co/docs
|
|
|
- $response = self::setBasicHttp()->get("https://ipapi.com/ip_api.php?ip=$ip");
|
|
|
+ $response = self::$basicRequest->get("https://ipapi.com/ip_api.php?ip=$ip");
|
|
|
if ($response->ok()) {
|
|
|
$data = $response->json();
|
|
|
|
|
|
@@ -626,39 +633,135 @@ class IP
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- public static function getIPGeo(string $ip): ?array
|
|
|
+ private static function vore(string $ip): ?array
|
|
|
+ { // 开发依据: https://api.vore.top/
|
|
|
+ $response = self::$basicRequest->get("https://api.vore.top/api/IPdata?ip=$ip");
|
|
|
+ if ($response->ok()) {
|
|
|
+ $data = $response->json();
|
|
|
+
|
|
|
+ if ($data['code'] === 200) {
|
|
|
+ return [
|
|
|
+ 'country' => $data['ipdata']['info1'],
|
|
|
+ 'region' => $data['ipdata']['info2'],
|
|
|
+ 'city' => $data['ipdata']['info3'],
|
|
|
+ 'isp' => $data['ipdata']['isp'],
|
|
|
+ 'area' => null,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static function vvhan(string $ip): ?array
|
|
|
+ {
|
|
|
+ $response = self::$basicRequest->get("https://api.vvhan.com/api/getIpInfo?ip=$ip");
|
|
|
+ if ($response->ok()) {
|
|
|
+ $data = $response->json();
|
|
|
+
|
|
|
+ if ($data['success'] && $data['ip'] === $ip) {
|
|
|
+ return [
|
|
|
+ 'country' => $data['info']['country'],
|
|
|
+ 'region' => $data['info']['prov'],
|
|
|
+ 'city' => $data['info']['city'],
|
|
|
+ 'isp' => $data['info']['isp'],
|
|
|
+ 'area' => null,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static function ipw(string $ip): ?array
|
|
|
+ { // 开发依据: https://api.vore.top/
|
|
|
+ if (self::$is_ipv4) {
|
|
|
+ $response = self::$basicRequest->asForm()->withHeaders(['Referer' => 'https://ipw.cn/'])->post('https://rest.ipw.cn/api/ip/queryThird',
|
|
|
+ ['ip' => $ip, 'param1' => '33546680dcec944422ee9fea64ced0fb6', 'param2' => '5ac8d31b5b3434350048af37a497a9']);
|
|
|
+ } else {
|
|
|
+ $response = self::$basicRequest->asForm()->withHeaders(['Referer' => 'https://ipw.cn/'])->get("https://rest.ipw.cn/api/aw/v1/ipv6?ip=$ip&warning=1");
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($response->ok()) {
|
|
|
+ $data = $response->json();
|
|
|
+ if (self::$is_ipv4) {
|
|
|
+ if ($data['result'] && $data['Result']['code'] === 'Success' && $data['Result']['ip'] === $ip) {
|
|
|
+ $data = $data['Result']['data'];
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'country' => $data['country'],
|
|
|
+ 'region' => $data['prov'],
|
|
|
+ 'city' => $data['city'],
|
|
|
+ 'isp' => $data['isp'],
|
|
|
+ 'area' => $data['district'],
|
|
|
+ 'latitude' => $data['lat'],
|
|
|
+ 'longitude' => $data['lng'],
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ } elseif ($data['code'] === 'Success' && $data['ip'] === $ip) {
|
|
|
+ $data = $data['data'];
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'country' => $data['country'],
|
|
|
+ 'region' => $data['prov'],
|
|
|
+ 'city' => $data['city'],
|
|
|
+ 'isp' => $data['isp'],
|
|
|
+ 'area' => $data['district'],
|
|
|
+ 'latitude' => $data['lat'],
|
|
|
+ 'longitude' => $data['lng'],
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static function bjjii(string $ip): ?array
|
|
|
+ { // 开发依据: https://api.bjjii.com/doc/77
|
|
|
+ $key = config('services.ip.bjjii_key');
|
|
|
+ if ($key) {
|
|
|
+ $response = self::$basicRequest->get("https://api.bjjii.com/api/ip/query?key=$key&ip=$ip");
|
|
|
+ if ($response->ok()) {
|
|
|
+ $data = $response->json();
|
|
|
+
|
|
|
+ if ($data['code'] === 200 && $data['data']['ip'] === $ip) {
|
|
|
+ $data = $data['data']['info'];
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'country' => $data['nation'],
|
|
|
+ 'region' => $data['province'],
|
|
|
+ 'city' => $data['city'],
|
|
|
+ 'isp' => $data['isp'],
|
|
|
+ 'area' => $data['district'],
|
|
|
+ 'latitude' => $data['lat'],
|
|
|
+ 'longitude' => $data['lng'],
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function getIPGeo(string $ip): array|false
|
|
|
{
|
|
|
- $ret = null;
|
|
|
- $source = 0;
|
|
|
- while ($source <= 13 && ($ret === null || (is_array($ret) && empty(array_filter($ret))))) {
|
|
|
- $ret = match ($source) {
|
|
|
- 0 => self::IPSB($ip),
|
|
|
- 1 => self::ipApi($ip),
|
|
|
- 2 => self::baiduBce($ip),
|
|
|
- 3 => self::ipinfo($ip),
|
|
|
- 4 => self::IP2Online($ip),
|
|
|
- 5 => self::speedtest($ip),
|
|
|
- 6 => self::Baidu($ip),
|
|
|
- 7 => self::ip234($ip),
|
|
|
- 8 => self::ipdata($ip),
|
|
|
- 9 => self::ipGeoLocation($ip),
|
|
|
- 10 => self::ipjiance($ip),
|
|
|
- 11 => self::ipApiCo($ip),
|
|
|
- 12 => self::ipApiCom($ip),
|
|
|
- 13 => self::ip2Location($ip),
|
|
|
- };
|
|
|
- $source++;
|
|
|
- }
|
|
|
-
|
|
|
- return Arr::only($ret, ['latitude', 'longitude']);
|
|
|
+ self::$ip = $ip;
|
|
|
+ self::$basicRequest = Http::timeout(10)->withOptions(['http_errors' => false])->withUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36');
|
|
|
+
|
|
|
+ $ret = self::IPLookup(['IPSB', 'ipApi', 'baiduBce', 'ipw', 'ipinfo', 'IP2Online', 'speedtest', 'bjjii', 'Baidu', 'ip234', 'ipdata', 'ipGeoLocation', 'ipjiance', 'ipApiCo', 'ipApiCom', 'ip2Location']);
|
|
|
+ if (is_array($ret)) {
|
|
|
+ return Arr::only($ret, ['latitude', 'longitude']);
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
private static function userAgentInfo(string $ip): ?array
|
|
|
- { // 开发依据: https://ip.useragentinfo.com/api
|
|
|
+ { // 开发依据: https://ip.useragentinfo.com/api 无法查外网的ip
|
|
|
if (self::$is_ipv4) {
|
|
|
- $response = self::setBasicHttp()->withBody("ip:$ip")->get('https://ip.useragentinfo.com/json');
|
|
|
+ $response = self::$basicRequest->withBody("ip:$ip")->get('https://ip.useragentinfo.com/json');
|
|
|
} else {
|
|
|
- $response = self::setBasicHttp()->get("https://ip.useragentinfo.com/ipv6/$ip");
|
|
|
+ $response = self::$basicRequest->get("https://ip.useragentinfo.com/ipv6/$ip");
|
|
|
}
|
|
|
|
|
|
if ($response->ok()) {
|