608 lines
19 KiB
PHP
608 lines
19 KiB
PHP
<?php
|
||
// 应用公共文件
|
||
use think\facade\Db;
|
||
use think\facade\Request;
|
||
use GuzzleHttp\Client;
|
||
use GuzzleHttp\Exception\GuzzleException;
|
||
|
||
function get_curl($url, $post = 0, $referer = 0, $cookie = 0, $ua = 0, $nobody = 0, $addheader = [])
|
||
{
|
||
$options = [
|
||
'timeout' => 10,
|
||
'verify' => false,
|
||
'headers' => [
|
||
'User-Agent' => $ua ?: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36'
|
||
],
|
||
'http_errors' => false // 不抛出异常
|
||
];
|
||
|
||
$options['headers'] = array_merge($options['headers'], $addheader);
|
||
if ($referer) {
|
||
$options['headers']['Referer'] = $referer;
|
||
}
|
||
if ($cookie) {
|
||
$options['headers']['Cookie'] = $cookie;
|
||
}
|
||
|
||
$method = 'GET';
|
||
if ($post) {
|
||
$method = 'POST';
|
||
if (!isset($options['headers']['Content-Type'])) {
|
||
$options['headers']['Content-Type'] = 'application/x-www-form-urlencoded';
|
||
}
|
||
if (is_array($post)) {
|
||
$options['form_params'] = $post;
|
||
} else {
|
||
$options['body'] = $post;
|
||
}
|
||
}
|
||
|
||
try {
|
||
$client = new Client();
|
||
$response = $client->request($method, $url, $options);
|
||
|
||
if ($nobody) {
|
||
return '';
|
||
}
|
||
|
||
return $response->getBody()->getContents();
|
||
} catch (GuzzleException $e) {
|
||
return '';
|
||
}
|
||
}
|
||
|
||
function real_ip($type = 0)
|
||
{
|
||
$ip = $_SERVER['REMOTE_ADDR'];
|
||
if ($type <= 0 && isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
|
||
foreach ($matches[0] as $xip) {
|
||
if (filter_var($xip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||
$ip = $xip;
|
||
break;
|
||
}
|
||
}
|
||
} elseif ($type <= 0 && isset($_SERVER['HTTP_CLIENT_IP']) && filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
||
} elseif ($type <= 1 && isset($_SERVER['HTTP_CF_CONNECTING_IP']) && filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||
$ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
|
||
} elseif ($type <= 1 && isset($_SERVER['HTTP_X_REAL_IP']) && filter_var($_SERVER['HTTP_X_REAL_IP'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||
$ip = $_SERVER['HTTP_X_REAL_IP'];
|
||
}
|
||
return $ip;
|
||
}
|
||
|
||
function strexists($string, $find)
|
||
{
|
||
return !(strpos($string, $find) === FALSE);
|
||
}
|
||
|
||
function dstrpos($string, $arr)
|
||
{
|
||
if (empty($string)) return false;
|
||
foreach ((array)$arr as $v) {
|
||
if (strpos($string, $v) !== false) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
function checkmobile()
|
||
{
|
||
$useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
|
||
$ualist = array('android', 'midp', 'nokia', 'mobile', 'iphone', 'ipod', 'blackberry', 'windows phone');
|
||
if ((dstrpos($useragent, $ualist) || strexists($_SERVER['HTTP_ACCEPT'], "VND.WAP") || strexists($_SERVER['HTTP_VIA'], "wap"))) {
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0)
|
||
{
|
||
$ckey_length = 4;
|
||
$key = md5($key);
|
||
$keya = md5(substr($key, 0, 16));
|
||
$keyb = md5(substr($key, 16, 16));
|
||
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';
|
||
$cryptkey = $keya.md5($keya.$keyc);
|
||
$key_length = strlen($cryptkey);
|
||
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
|
||
$string_length = strlen($string);
|
||
$result = '';
|
||
$box = range(0, 255);
|
||
$rndkey = array();
|
||
for ($i = 0; $i <= 255; $i++) {
|
||
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
|
||
}
|
||
for ($j = $i = 0; $i < 256; $i++) {
|
||
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
|
||
$tmp = $box[$i];
|
||
$box[$i] = $box[$j];
|
||
$box[$j] = $tmp;
|
||
}
|
||
for ($a = $j = $i = 0; $i < $string_length; $i++) {
|
||
$a = ($a + 1) % 256;
|
||
$j = ($j + $box[$a]) % 256;
|
||
$tmp = $box[$a];
|
||
$box[$a] = $box[$j];
|
||
$box[$j] = $tmp;
|
||
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
|
||
}
|
||
if ($operation == 'DECODE') {
|
||
if (((int)substr($result, 0, 10) == 0 || (int)substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
|
||
return substr($result, 26);
|
||
} else {
|
||
return '';
|
||
}
|
||
} else {
|
||
return $keyc.base64_encode($result);
|
||
}
|
||
}
|
||
|
||
function random($length, $numeric = 0)
|
||
{
|
||
$seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
|
||
$seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));
|
||
$hash = '';
|
||
$max = strlen($seed) - 1;
|
||
for ($i = 0; $i < $length; $i++) {
|
||
$hash .= $seed[mt_rand(0, $max)];
|
||
}
|
||
return $hash;
|
||
}
|
||
|
||
function checkDomain($domain)
|
||
{
|
||
if (empty($domain) || !preg_match('/^[-$a-z0-9_*.]{2,512}$/i', $domain) || (stripos($domain, '.') === false) || substr($domain, -1) == '.' || substr($domain, 0, 1) == '.' || substr($domain, 0, 1) == '*' && substr($domain, 1, 1) != '.' || substr_count($domain, '*') > 1 || strpos($domain, '*') > 0 || strlen($domain) < 4) return false;
|
||
return true;
|
||
}
|
||
|
||
function getSubstr($str, $leftStr, $rightStr)
|
||
{
|
||
$left = strpos($str, $leftStr);
|
||
$start = $left + strlen($leftStr);
|
||
$right = strpos($str, $rightStr, $start);
|
||
if ($left < 0) return '';
|
||
if ($right > 0) {
|
||
return substr($str, $start, $right - $start);
|
||
} else {
|
||
return substr($str, $start);
|
||
}
|
||
}
|
||
|
||
function arrays_are_equal($array1, $array2)
|
||
{
|
||
return empty(array_diff($array1, $array2)) && empty(array_diff($array2, $array1));
|
||
}
|
||
|
||
function checkRefererHost()
|
||
{
|
||
if (!Request::header('referer')) {
|
||
return false;
|
||
}
|
||
$url_arr = parse_url(Request::header('referer'));
|
||
$http_host = Request::header('host');
|
||
if (strpos($http_host, ':')) {
|
||
$http_host = substr($http_host, 0, strpos($http_host, ':'));
|
||
}
|
||
return $url_arr['host'] === $http_host;
|
||
}
|
||
|
||
function checkIfActive($string)
|
||
{
|
||
$array = explode(',', $string);
|
||
$action = Request::action();
|
||
if (in_array($action, $array)) {
|
||
return 'active';
|
||
} else {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
function getSid()
|
||
{
|
||
return md5(uniqid(mt_rand(), true) . microtime());
|
||
}
|
||
function getMd5Pwd($pwd, $salt = null)
|
||
{
|
||
return md5(md5($pwd) . md5('1277180438'.$salt));
|
||
}
|
||
|
||
function isNullOrEmpty($str)
|
||
{
|
||
return $str === null || $str === '';
|
||
}
|
||
|
||
function checkPermission($type, $domain = null)
|
||
{
|
||
$user = Request()->user;
|
||
if (empty($user)) {
|
||
return false;
|
||
}
|
||
if ($user['level'] == 2) {
|
||
return true;
|
||
}
|
||
if ($type == 1 && $user['level'] == 1 || $type == 0 && $user['level'] >= 0) {
|
||
if ($domain == null) {
|
||
return true;
|
||
}
|
||
if (in_array($domain, $user['permission'])) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
function getAdminSkin()
|
||
{
|
||
$skin = cookie('admin_skin');
|
||
if (empty($skin)) {
|
||
$skin = config_get('admin_skin');
|
||
}
|
||
if (empty($skin)) {
|
||
$skin = 'skin-black-blue';
|
||
}
|
||
return $skin;
|
||
}
|
||
|
||
function config_get($key, $default = null, $force = false)
|
||
{
|
||
if ($force) {
|
||
$value = Db::name('config')->where('key', $key)->value('value');
|
||
} else {
|
||
$value = config('sys.' . $key);
|
||
}
|
||
return $value ?: $default;
|
||
}
|
||
|
||
function config_set($key, $value)
|
||
{
|
||
$res = Db::name('config')->replace()->insert(['key' => $key, 'value' => $value]);
|
||
return $res !== false;
|
||
}
|
||
|
||
function getMillisecond()
|
||
{
|
||
list($s1, $s2) = explode(' ', microtime());
|
||
return (int)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
|
||
}
|
||
|
||
function getDnsType($value)
|
||
{
|
||
if (filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||
return 'A';
|
||
} elseif (filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||
return 'AAAA';
|
||
} else {
|
||
return 'CNAME';
|
||
}
|
||
}
|
||
|
||
function convert_second($s)
|
||
{
|
||
$m = floor($s / 60);
|
||
if ($m == 0) {
|
||
return $s.'秒';
|
||
} else {
|
||
$s = $s % 60;
|
||
$h = floor($m / 60);
|
||
if ($h == 0) {
|
||
return $m.'分钟'.$s.'秒';
|
||
} else {
|
||
$m = $m % 60;
|
||
return $h.'小时'.$m.'分钟'.$s.'秒';
|
||
}
|
||
}
|
||
}
|
||
|
||
function getMainDomain($host)
|
||
{
|
||
if (filter_var($host, FILTER_VALIDATE_IP)) return $host;
|
||
$domains = config('temp.domains');
|
||
if (!$domains) {
|
||
$domains = Db::name('domain')->column('name');
|
||
config(['domains'=>$domains], 'temp');
|
||
}
|
||
foreach ($domains as $domain) {
|
||
if (str_ends_with($host, $domain)) {
|
||
return $domain;
|
||
}
|
||
}
|
||
$domain_root = file_get_contents(app()->getBasePath() . 'data' . DIRECTORY_SEPARATOR . 'domain_root.txt');
|
||
$domain_root = explode("\r\n", $domain_root);
|
||
$data = explode('.', $host);
|
||
$co_ta = count($data);
|
||
if ($co_ta <= 2) return $host;
|
||
$domain_name = $data[$co_ta - 2] . '.' . $data[$co_ta - 1];
|
||
if (in_array($domain_name, $domain_root) && $co_ta > 2) {
|
||
$domain_name = $data[$co_ta - 3] . '.' . $domain_name;
|
||
}
|
||
return $domain_name;
|
||
}
|
||
|
||
function check_proxy($url, $proxy_server, $proxy_port, $type, $proxy_user, $proxy_pwd)
|
||
{
|
||
match ($type) {
|
||
'https' => $proxy_string = 'https://',
|
||
'sock4' => $proxy_string = 'socks4://',
|
||
'sock5' => $proxy_string = 'socks5://',
|
||
'sock5h' => $proxy_string = 'socks5h://',
|
||
default => $proxy_string = 'http://',
|
||
};
|
||
|
||
if (!empty($proxy_user) && !empty($proxy_pwd)) {
|
||
$proxy_string .= $proxy_user . ':' . $proxy_pwd . '@';
|
||
}
|
||
|
||
$proxy_string .= $proxy_server . ':' . intval($proxy_port);
|
||
$options = [
|
||
'proxy' => $proxy_string,
|
||
'timeout' => 3,
|
||
'connect_timeout' => 3,
|
||
'verify' => false,
|
||
'headers' => [
|
||
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36'
|
||
]
|
||
];
|
||
|
||
try {
|
||
$client = new Client();
|
||
$response = $client->request('GET', $url, $options);
|
||
$httpCode = $response->getStatusCode();
|
||
|
||
if ($httpCode >= 200 && $httpCode < 400) {
|
||
return true;
|
||
} else {
|
||
throw new Exception('HTTP状态码异常:' . $httpCode);
|
||
}
|
||
} catch (GuzzleException $e) {
|
||
throw new Exception(guzzle_error($e));
|
||
}
|
||
}
|
||
|
||
function clearDirectory($dir): bool
|
||
{
|
||
// 确保路径是目录
|
||
if (!is_dir($dir)) {
|
||
return false;
|
||
}
|
||
|
||
// 打开目录
|
||
$items = scandir($dir);
|
||
foreach ($items as $item) {
|
||
// 跳过 '.' 和 '..'
|
||
if ($item == '.' || $item == '..') {
|
||
continue;
|
||
}
|
||
|
||
// 完整路径
|
||
$path = $dir . DIRECTORY_SEPARATOR . $item;
|
||
|
||
// 如果是目录,递归删除其内容
|
||
if (is_dir($path)) {
|
||
clearDirectory($path);
|
||
// 删除空目录
|
||
rmdir($path);
|
||
} else {
|
||
// 删除文件
|
||
unlink($path);
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 发送 HTTP 请求
|
||
*
|
||
* @param string $url 请求URL
|
||
* @param mixed $data 请求数据,可以是字符串或数组,数组将自动根据请求方法及传入的 Content-Type 头序列化
|
||
* @param string|null $referer 请求的 Referer 头
|
||
* @param array|null $cookie 请求的 Cookie 头
|
||
* @param array|null $headers 其他自定义请求头
|
||
* @param bool $proxy 是否使用代理
|
||
* @param string|null $method 请求方法,默认为 GET 或 POST(如果存在请求数据)
|
||
* @param int $timeout 请求超时时间,默认为 10 秒
|
||
* @return array 包含 HTTP 状态码、重定向 URL、响应头和响应体的数组
|
||
* @throws Exception
|
||
*/
|
||
function http_request($url, $data = null, $referer = null, $cookie = null, $headers = null, $proxy = false, $method = null, $timeout = 10): array
|
||
{
|
||
$options = [
|
||
'timeout' => $timeout,
|
||
'connect_timeout' => $timeout,
|
||
'allow_redirects' => false,
|
||
'verify' => false,
|
||
'headers' => [
|
||
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36',
|
||
],
|
||
'http_errors' => false // 不抛出异常
|
||
];
|
||
|
||
// 默认请求方法
|
||
if (!$method) {
|
||
$method = $data ? 'POST' : 'GET';
|
||
}
|
||
// 处理头部
|
||
if (is_array($headers)) {
|
||
$options['headers'] = array_merge($options['headers'], $headers);
|
||
}
|
||
// 处理Cookie
|
||
if ($cookie) {
|
||
$options['headers']['Cookie'] = $cookie;
|
||
}
|
||
// 处理Referer
|
||
if ($referer) {
|
||
$options['headers']['Referer'] = $referer;
|
||
}
|
||
// 处理数据
|
||
if ($data) {
|
||
if ($method !== 'GET') {
|
||
if (is_string($data)) {
|
||
$options['body'] = $data;
|
||
if (!isset($options['headers']['Content-Type'])) {
|
||
if (json_validate($data)) {
|
||
// json
|
||
$options['headers']['Content-Type'] = 'application/json';
|
||
} elseif (str_contains($data, '=') || str_contains($data, '&')) {
|
||
// 表单
|
||
$options['headers']['Content-Type'] = 'application/x-www-form-urlencoded';
|
||
}
|
||
}
|
||
} else if (is_array($data) || is_object($data)) {
|
||
if (!isset($options['headers']['Content-Type'])) {
|
||
// 默认为表单
|
||
$options['headers']['Content-Type'] = 'application/x-www-form-urlencoded';
|
||
}
|
||
if ($options['headers']['Content-Type'] == 'application/x-www-form-urlencoded') {
|
||
// 表单
|
||
$options['form_params'] = $data;
|
||
} else if ($options['headers']['Content-Type'] == 'multipart/form-data') {
|
||
// 表单文件
|
||
$options['multipart'] = $data;
|
||
unset($options['headers']['Content-Type']); // 由GuzzleHttp重新生成Content-Type头部
|
||
} else if ($options['headers']['Content-Type'] == 'application/json') {
|
||
// json
|
||
$options['json'] = $data;
|
||
} else {
|
||
// 其他
|
||
$options['body'] = http_build_query($data);
|
||
}
|
||
} else {
|
||
$options['body'] = $data;
|
||
}
|
||
} else {
|
||
// 兼容已经存在查询字符串的情况
|
||
if (!str_contains($url, '?')) {
|
||
$options['query'] = $data;
|
||
}
|
||
}
|
||
}
|
||
// 处理代理
|
||
if ($proxy) {
|
||
$proxy_server = config_get('proxy_server');
|
||
$proxy_port = intval(config_get('proxy_port'));
|
||
$proxy_userpwd = config_get('proxy_user').':'.config_get('proxy_pwd');
|
||
$proxy_type = config_get('proxy_type');
|
||
|
||
if (empty($proxy_server) || empty($proxy_port)) {
|
||
throw new Exception('代理服务器或端口未配置');
|
||
}
|
||
|
||
match ($proxy_type) {
|
||
'https' => $proxy_string = 'https://',
|
||
'sock4' => $proxy_string = 'socks4://',
|
||
'sock5' => $proxy_string = 'socks5://',
|
||
'sock5h' => $proxy_string = 'socks5h://',
|
||
default => $proxy_string = 'http://',
|
||
};
|
||
|
||
if ($proxy_userpwd != ':') {
|
||
$proxy_string .= $proxy_userpwd . '@';
|
||
}
|
||
|
||
$proxy_string .= $proxy_server . ':' . $proxy_port;
|
||
$options['proxy'] = $proxy_string;
|
||
}
|
||
|
||
try {
|
||
$client = new Client();
|
||
$response = $client->request($method, $url, $options);
|
||
$code = $response->getStatusCode();
|
||
|
||
// 取重定向URL
|
||
$redirect_url = '';
|
||
if ($code >= 300 && $code < 400) {
|
||
$redirect_url = $response->getHeaderLine('Location');
|
||
}
|
||
|
||
return [
|
||
'code' => $code,
|
||
'redirect_url' => $redirect_url,
|
||
'headers' => $response->getHeaders(),
|
||
'body' => $response->getBody()->getContents()
|
||
];
|
||
} catch (GuzzleException $e) {
|
||
throw new Exception('请求失败: ' . guzzle_error($e));
|
||
}
|
||
}
|
||
|
||
function guzzle_error($e)
|
||
{
|
||
$errmsg = $e->getMessage();
|
||
if (preg_match('/^cURL error \d+: /', $errmsg)) {
|
||
$errmsg = preg_replace('/^cURL error \d+: /', '', $errmsg);
|
||
}
|
||
$pos = strpos($errmsg, ' (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)');
|
||
if ($pos !== false) {
|
||
$errmsg = substr($errmsg, 0, $pos);
|
||
}
|
||
if (strlen($errmsg) > 100) {
|
||
$errmsg = substr($errmsg, 0, 97) . '...';
|
||
}
|
||
return $errmsg;
|
||
}
|
||
|
||
function curl_set_proxy(&$ch)
|
||
{
|
||
$proxy_server = config_get('proxy_server');
|
||
$proxy_port = intval(config_get('proxy_port'));
|
||
$proxy_userpwd = config_get('proxy_user') . ':' . config_get('proxy_pwd');
|
||
$proxy_type = config_get('proxy_type');
|
||
if (empty($proxy_server) || empty($proxy_port)) {
|
||
return;
|
||
}
|
||
if ($proxy_type == 'https') {
|
||
$proxy_type = CURLPROXY_HTTPS;
|
||
} elseif ($proxy_type == 'sock4') {
|
||
$proxy_type = CURLPROXY_SOCKS4;
|
||
} elseif ($proxy_type == 'sock5') {
|
||
$proxy_type = CURLPROXY_SOCKS5;
|
||
} elseif ($proxy_type == 'sock5h') {
|
||
$proxy_type = CURLPROXY_SOCKS5_HOSTNAME;
|
||
} else {
|
||
$proxy_type = CURLPROXY_HTTP;
|
||
}
|
||
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
|
||
curl_setopt($ch, CURLOPT_PROXY, $proxy_server);
|
||
curl_setopt($ch, CURLOPT_PROXYPORT, $proxy_port);
|
||
if ($proxy_userpwd != ':') {
|
||
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxy_userpwd);
|
||
}
|
||
curl_setopt($ch, CURLOPT_PROXYTYPE, $proxy_type);
|
||
}
|
||
|
||
function convertDomainToAscii($domain) {
|
||
if (preg_match('/[\x{4e00}-\x{9fa5}]/u', $domain)) {
|
||
return idn_to_ascii($domain);
|
||
} else {
|
||
return $domain;
|
||
}
|
||
}
|
||
function convertDomainToUtf8($domain) {
|
||
if (preg_match('/^xn--/', $domain)) {
|
||
return idn_to_utf8($domain);
|
||
} else {
|
||
return $domain;
|
||
}
|
||
}
|
||
|
||
function getDomainDate($domain)
|
||
{
|
||
try {
|
||
$whois = \Iodev\Whois\Factory::get()->createWhois();
|
||
$info = $whois->loadDomainInfo($domain);
|
||
if ($info) {
|
||
if ($info->expirationDate > 0) {
|
||
return [$info->creationDate > 0 ? date('Y-m-d H:i:s', $info->creationDate) : null, date('Y-m-d H:i:s', $info->expirationDate)];
|
||
} else {
|
||
throw new Exception('域名到期时间未知');
|
||
}
|
||
} else {
|
||
throw new Exception('域名信息未找到');
|
||
}
|
||
} catch (Exception $e) {
|
||
throw new Exception('查询域名whois失败: ' . $e->getMessage());
|
||
}
|
||
}
|