changeCoor(abs($lat)); $str .= ($lat < 0) ? 'S' : 'N'; $lon = number_format(trim(explode(',', $rawStr)[1]), 8); // 经度 $str .= ', ' . $this->changeCoor(abs($lon)); $str .= ($lon < 0) ? 'W' : 'E'; $str .= ')'; return $str; } public function getInfo($ip) { if (!filter_var($ip, FILTER_VALIDATE_IP)) { // IP地址不合法 return array( 'status' => 'error', 'message' => 'Illegal IP Address' ); } $redis = new redisCache('ip'); $info = $redis->getData($ip); // 查询缓存数据 if (!$info) { // 缓存未命中 $info = json_decode(file_get_contents($this->apiPath . $ip), true); if ($info['status'] !== 'T') { // 上游接口错误 return array( 'status' => 'error', 'message' => 'Server Error' ); } unset($info['status']); if ($info['loc'] != NULL) { $info['locCoor'] = $this->coorFormat($info['loc']); // 转换为经纬度格式 } $redis->setData($ip, json_encode($info), 1800); // 缓存30min } else { // 缓存命中 $info = json_decode($info, true); // 使用缓存数据 } return array( 'status' => 'ok', 'data' => json_encode($info) // 返回查询结果 ); } } class ipInfoEntry { private function isDomain($domain) { // 检测是否为域名 preg_match('/^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$/', $domain, $match); return (count($match) != 0); } private function dnsResolveIPv4($domain) { // DNS解析A记录 $ipAddr = array(); $rs = dns_get_record(strtolower($domain), DNS_A); foreach ($rs as $record) { $ipAddr[] = $record['ip']; } return $ipAddr; } private function dnsResolveIPv6($domain) { // DNS解析AAAA记录 $ipAddr = array(); $rs = dns_get_record(strtolower($domain), DNS_AAAA); foreach ($rs as $record) { $ipAddr[] = $record['ipv6']; } return $ipAddr; } private function dnsResolve($domain) { // DNS解析IP记录 $ipAddr = array(); $ipv4 = $this->dnsResolveIPv4($domain); foreach ($ipv4 as $ip) { $ipAddr[] = $ip; } $ipv6 = $this->dnsResolveIPv6($domain); foreach ($ipv6 as $ip) { $ipAddr[] = $ip; } return $ipAddr; } private function getInfo($ip) { $content = (new ipInfo)->getInfo($ip); // 发起查询 if ($content['status'] !== 'ok') { return array( 'text' => $content['message'] // 返回错误信息 ); } $info = json_decode($content['data'], true); $msg = 'IP: ' . $info['ip'] . '' . PHP_EOL; if ($info['as'] != NULL) { $msg .= 'AS: '; $msg .= $info['as'] . '' . PHP_EOL; } if ($info['loc'] != NULL) { $msg .= 'Location: '; $msg .= $info['locCoor'] . '' . PHP_EOL; } if ($info['city'] != NULL) { $msg .= 'City: ' . $info['city'] . PHP_EOL; } if ($info['region'] != NULL) { $msg .= 'Region: ' . $info['region'] . PHP_EOL; } if ($info['country'] != NULL) { $msg .= 'Country: ' . $info['country'] . PHP_EOL; } if ($info['timezone'] != NULL) { $msg .= 'Timezone: ' . $info['timezone'] . PHP_EOL; } if ($info['isp'] != NULL) { $msg .= 'ISP: ' . $info['isp'] . PHP_EOL; } if ($info['scope'] != NULL) { $msg .= 'Scope: ' . $info['scope'] . '' . PHP_EOL; } if ($info['detail'] != NULL) { $msg .= 'Detail: ' . $info['detail'] . PHP_EOL; } return array( 'parse_mode' => 'HTML', // HTML格式输出 'disable_web_page_preview' => 'true', // 不显示页面预览 'text' => $msg, 'reply_markup' => json_encode(array( // 显示按钮 'inline_keyboard' => array([[ 'text' => 'View on echoIP', 'url' => 'https://ip.dnomd343.top/?ip=' . $ip ]]) )) ); } public function query($rawParam) { // ipInfo查询入口 if ($rawParam == '' || $rawParam === 'help') { // 显示使用说明 tgApi::sendMessage(array( 'parse_mode' => 'Markdown', 'text' => '*Usage:* `/ip IPv4/IPv6/Domain`', 'reply_markup' => json_encode(array( // 显示echoIP按钮 'inline_keyboard' => array([[ 'text' => 'Get my IP address', 'url' => 'https://ip.dnomd343.top/' ]]) )) )); return; } if (filter_var($rawParam, FILTER_VALIDATE_IP)) { // 参数为IP地址 tgApi::sendMessage($this->getInfo($rawParam)); // 发起查询 return; } if (!$this->isDomain($rawParam)) { tgApi::sendText('Illegal Request'); // 非法请求 return; } $ips = $this->dnsResolve($rawParam); if (count($ips) == 0) { // 解析不到IP记录 tgApi::sendMessage($chatId, array( 'parse_mode' => 'Markdown', 'text' => 'Nothing found of `' . $rawParam . '`' )); return; } foreach ($ips as $ip) { $buttons[] = array([ // 生成按钮列表 'text' => $ip, 'callback_data' => '/ip ' . $ip ]); } if (count($ips) >= 2) { $buttons[] = array([ // 两个及以上的IP 添加显示全部的按钮 'text' => 'Get all detail', 'callback_data' => '/ip ' . $rawParam ]); } tgApi::sendMessage(array( 'parse_mode' => 'Markdown', 'text' => 'DNS resolve of `' . $rawParam . '`', 'reply_markup' => json_encode(array( // 显示IP列表按钮 'inline_keyboard' => $buttons )) )); } public function callback($rawParam) { // ipInfo回调入口 if (filter_var($rawParam, FILTER_VALIDATE_IP)) { // 参数为IP地址 $this->query($rawParam); } else { // 参数为域名 global $tgEnv; tgApi::deleteMessage(array( 'message_id' => $tgEnv['messageId'] )); $ips = $this->dnsResolve($rawParam); foreach ($ips as $ip) { $this->query($ip); // 逐个输出 } } } } ?>