first commit
This commit is contained in:
266
includes/utils.php
Normal file
266
includes/utils.php
Normal file
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
/**
|
||||
* 工具类文件
|
||||
* 包含URL抓取、重复检测、IP限制等功能
|
||||
*/
|
||||
|
||||
class Utils {
|
||||
private $db;
|
||||
|
||||
public function __construct($database) {
|
||||
$this->db = $database;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取网站TDK信息
|
||||
*/
|
||||
public function getWebsiteInfo($url) {
|
||||
// 确保URL包含协议
|
||||
if (!preg_match('/^https?:\/\//i', $url)) {
|
||||
$url = 'http://' . $url;
|
||||
}
|
||||
|
||||
$result = [
|
||||
'title' => '',
|
||||
'description' => '',
|
||||
'keywords' => '',
|
||||
'url' => $url,
|
||||
'success' => false
|
||||
];
|
||||
|
||||
try {
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'timeout' => 10,
|
||||
'user_agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
|
||||
]
|
||||
]);
|
||||
|
||||
$html = @file_get_contents($url, false, $context);
|
||||
|
||||
if ($html === false) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// 转换编码
|
||||
$html = mb_convert_encoding($html, 'UTF-8', 'auto');
|
||||
|
||||
// 解析HTML
|
||||
$dom = new DOMDocument();
|
||||
@$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
|
||||
// 获取title
|
||||
$titles = $dom->getElementsByTagName('title');
|
||||
if ($titles->length > 0) {
|
||||
$result['title'] = trim($titles->item(0)->textContent);
|
||||
}
|
||||
|
||||
// 获取meta标签
|
||||
$metas = $dom->getElementsByTagName('meta');
|
||||
foreach ($metas as $meta) {
|
||||
$name = $meta->getAttribute('name');
|
||||
$property = $meta->getAttribute('property');
|
||||
$content = $meta->getAttribute('content');
|
||||
|
||||
if (strtolower($name) === 'description' || strtolower($property) === 'og:description') {
|
||||
if (empty($result['description'])) {
|
||||
$result['description'] = trim($content);
|
||||
}
|
||||
}
|
||||
|
||||
if (strtolower($name) === 'keywords') {
|
||||
$result['keywords'] = trim($content);
|
||||
}
|
||||
}
|
||||
|
||||
$result['success'] = true;
|
||||
|
||||
} catch (Exception $e) {
|
||||
// 静默处理错误
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查IP提交限制
|
||||
*/
|
||||
public function checkIPLimit($ip) {
|
||||
$today = date('Y-m-d');
|
||||
|
||||
$stmt = $this->db->prepare("
|
||||
SELECT count FROM ip_submissions
|
||||
WHERE ip_address = ? AND submission_date = ?
|
||||
");
|
||||
$stmt->execute([$ip, $today]);
|
||||
$result = $stmt->fetch();
|
||||
|
||||
if ($result) {
|
||||
return $result['count'] < 3;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录IP提交
|
||||
*/
|
||||
public function recordIPSubmission($ip) {
|
||||
$today = date('Y-m-d');
|
||||
|
||||
$stmt = $this->db->prepare("
|
||||
INSERT INTO ip_submissions (ip_address, submission_date, count)
|
||||
VALUES (?, ?, 1)
|
||||
ON DUPLICATE KEY UPDATE count = count + 1
|
||||
");
|
||||
|
||||
try {
|
||||
$stmt->execute([$ip, $today]);
|
||||
} catch (PDOException $e) {
|
||||
// SQLite兼容处理
|
||||
$check = $this->db->prepare("
|
||||
SELECT count FROM ip_submissions
|
||||
WHERE ip_address = ? AND submission_date = ?
|
||||
");
|
||||
$check->execute([$ip, $today]);
|
||||
$existing = $check->fetch();
|
||||
|
||||
if ($existing) {
|
||||
$update = $this->db->prepare("
|
||||
UPDATE ip_submissions
|
||||
SET count = count + 1
|
||||
WHERE ip_address = ? AND submission_date = ?
|
||||
");
|
||||
$update->execute([$ip, $today]);
|
||||
} else {
|
||||
$insert = $this->db->prepare("
|
||||
INSERT INTO ip_submissions (ip_address, submission_date, count)
|
||||
VALUES (?, ?, 1)
|
||||
");
|
||||
$insert->execute([$ip, $today]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查网址重复
|
||||
*/
|
||||
public function checkWebsiteDuplicate($url) {
|
||||
// 标准化URL
|
||||
$normalized_url = $this->normalizeUrl($url);
|
||||
$domain = $this->extractDomain($url);
|
||||
|
||||
$stmt = $this->db->prepare("
|
||||
SELECT id FROM website_submissions
|
||||
WHERE url = ? OR url LIKE ?
|
||||
");
|
||||
$stmt->execute([$normalized_url, '%' . $domain . '%']);
|
||||
|
||||
return $stmt->fetch() !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查APP重复
|
||||
*/
|
||||
public function checkAppDuplicate($name, $platform) {
|
||||
$stmt = $this->db->prepare("
|
||||
SELECT id FROM app_submissions
|
||||
WHERE name = ? AND platform = ?
|
||||
");
|
||||
$stmt->execute([$name, $platform]);
|
||||
|
||||
return $stmt->fetch() !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 标准化URL
|
||||
*/
|
||||
private function normalizeUrl($url) {
|
||||
// 移除协议
|
||||
$url = preg_replace('/^https?:\/\//i', '', $url);
|
||||
// 移除www
|
||||
$url = preg_replace('/^www\./i', '', $url);
|
||||
// 移除尾部斜杠
|
||||
$url = rtrim($url, '/');
|
||||
// 转换为小写
|
||||
$url = strtolower($url);
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取域名
|
||||
*/
|
||||
private function extractDomain($url) {
|
||||
$parsed = parse_url($url);
|
||||
$host = isset($parsed['host']) ? $parsed['host'] : $url;
|
||||
|
||||
// 移除www
|
||||
$host = preg_replace('/^www\./i', '', $host);
|
||||
|
||||
return strtolower($host);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端IP
|
||||
*/
|
||||
public static function getClientIP() {
|
||||
$ip_keys = ['HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'HTTP_CLIENT_IP', 'REMOTE_ADDR'];
|
||||
|
||||
foreach ($ip_keys as $key) {
|
||||
if (!empty($_SERVER[$key])) {
|
||||
$ip = $_SERVER[$key];
|
||||
if (strpos($ip, ',') !== false) {
|
||||
$ip = trim(explode(',', $ip)[0]);
|
||||
}
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||||
return $ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成验证码
|
||||
*/
|
||||
public static function generateCaptcha() {
|
||||
session_start();
|
||||
|
||||
$code = '';
|
||||
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$code .= $chars[rand(0, strlen($chars) - 1)];
|
||||
}
|
||||
|
||||
$_SESSION['captcha'] = $code;
|
||||
|
||||
// 创建图片
|
||||
$image = imagecreate(100, 40);
|
||||
$bg_color = imagecolorallocate($image, 255, 255, 255);
|
||||
$text_color = imagecolorallocate($image, 0, 0, 0);
|
||||
$line_color = imagecolorallocate($image, 200, 200, 200);
|
||||
|
||||
// 添加干扰线
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
imageline($image, rand(0, 100), rand(0, 40), rand(0, 100), rand(0, 40), $line_color);
|
||||
}
|
||||
|
||||
// 添加文字
|
||||
imagestring($image, 5, 25, 12, $code, $text_color);
|
||||
|
||||
header('Content-Type: image/png');
|
||||
imagepng($image);
|
||||
imagedestroy($image);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证验证码
|
||||
*/
|
||||
public static function verifyCaptcha($input) {
|
||||
session_start();
|
||||
return isset($_SESSION['captcha']) && strtoupper($input) === $_SESSION['captcha'];
|
||||
}
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user