logFile = $logFile; } public function log(string $page, string $ip, string $userAgent, string $referrer, string $host, string $acceptLanguage): void { $dir = dirname($this->logFile); if (!is_dir($dir)) { @mkdir($dir, 0755, true); } $timestamp = date('Y-m-d H:i:s'); $ua = substr(preg_replace('/[[:cntrl:]]/', '', $userAgent), 0, 500); $ref = substr(preg_replace('/[[:cntrl:]]/', '', $referrer), 0, 500); $line = "[{$timestamp}] [{$ip}] [{$host}] [{$acceptLanguage}] [{$page}] [{$ua}] [{$ref}]\n"; @file_put_contents($this->logFile, $line, FILE_APPEND | LOCK_EX); } public static function detectBot(): ?string { $ua = $_SERVER['HTTP_USER_AGENT'] ?? ''; if (empty($ua)) return null; $bots = [ 'AI' => [ 'GPTBot', 'ChatGPT-User', 'Claude-Web', 'ClaudeBot', 'anthropic-ai', 'Google-Extended', 'CCBot', 'PerplexityBot', 'Amazonbot', 'cohere-ai', 'OAI-SearchBot', 'Bytespider', 'FacebookBot', 'Applebot-Extended', ], 'Search' => [ 'Googlebot', 'Bingbot', 'BingPreview', 'Slurp', 'DuckDuckBot', 'Baiduspider', 'YandexBot', 'Sogou', 'Exabot', 'facebot', ], 'Scraper' => [ 'HTTrack', 'Scrapy', 'PhantomJS', 'HeadlessChrome', ], ]; foreach ($bots as $category => $patterns) { foreach ($patterns as $pattern) { if (stripos($ua, $pattern) !== false) { return $category; } } } return null; } public function getLogs(int $lines = 100): array { if (!file_exists($this->logFile)) { return []; } $content = file($this->logFile); $content = array_slice($content, -$lines); $logs = []; foreach ($content as $line) { if (preg_match('/^\[([^\]]+)\] \[([^\]]+)\] \[([^\]]+)\] \[([^\]]*)\] \[([^\]]+)\] \[([^\]]*)\] \[([^\]]*)\]$/', trim($line), $m)) { $logs[] = [ 'time' => $m[1], 'ip' => $m[2], 'host' => $m[3], 'lang' => $m[4], 'page' => $m[5], 'ua' => $m[6], 'referrer' => $m[7], ]; } } return array_reverse($logs); } }