tougao/includes/utils.php

266 lines
7.6 KiB
PHP
Raw Normal View History

2025-05-26 15:23:18 +08:00
<?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'];
}
}
?>