В этой статье разберём рабочий PHP‑скрипт для подсчёта реальных просмотров страницы с фильтрацией ботов. Код не требует JavaScript и опирается на анализ HTTP‑запросов.
<?php // Пути к файлам $counterFile = 'visits.txt'; $logFile = 'visits_log.txt'; // 1. Собираем данные о посетителе $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown'; $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown'; // Определяем ОС function getOS($userAgent) { $os = 'Unknown'; if (strpos($userAgent, 'Windows') !== false) { $os = 'Windows'; } elseif (strpos($userAgent, 'Mac OS X') !== false) { $os = 'MacOS'; } elseif (strpos($userAgent, 'Linux') !== false && strpos($userAgent, 'Android') === false) { $os = 'Linux'; } elseif (strpos($userAgent, 'Android') !== false) { $os = 'Android'; } elseif (strpos($userAgent, 'iPhone') !== false || strpos($userAgent, 'iPad') !== false) { $os = 'iOS'; } return $os; } // Определяем браузер function getBrowser($userAgent) { $browser = 'Unknown'; if (strpos($userAgent, 'Firefox') !== false) { $browser = 'Firefox'; } elseif (strpos($userAgent, 'Chrome') !== false && strpos($userAgent, 'Edg') === false && strpos($userAgent, 'Headless') === false) { $browser = 'Chrome'; } elseif (strpos($userAgent, 'Safari') !== false && strpos($userAgent, 'Chrome') === false) { $browser = 'Safari'; } elseif (strpos($userAgent, 'Edg') !== false) { $browser = 'Edge'; } elseif (strpos($userAgent, 'Opera') !== false || strpos($userAgent, 'OPR') !== false) { $browser = 'Opera'; } elseif (strpos($userAgent, 'MSIE') !== false || strpos($userAgent, 'Trident') !== false) { $browser = 'Internet Explorer'; } return $browser; } $os = getOS($userAgent); $browser = getBrowser($userAgent); // 2. Проверяем, похож ли посетитель на бота (без JS) $isBot = false; // а) Проверка User‑Agent на ботовские маркеры $botPattern = '/(bot|crawler|spider|slurp|scrapy|wget|curl|phantomjs|headless|automation|yandex|googlebot|bingbot)(?!chrome|firefox|safari|edge|opera|msie|trident)/i'; if (preg_match($botPattern, $userAgent)) { $isBot = true; error_log("[BOT] User-Agent помечен как бот: $userAgent"); } // б) Проверка обязательных HTTP‑заголовков (с резервным вариантом) $hasAccept = isset($_SERVER['HTTP_ACCEPT']); $hasAcceptLanguage = isset($_SERVER['HTTP_ACEPT_LANGUAGE']); if (!$hasAccept && !$hasAcceptLanguage) { // Только если ОБА заголовка отсутствуют → считаем ботом $isBot = true; error_log("[BOT] Нет ни Accept, ни Accept-Language (IP: $ip)"); } elseif (!$hasAcceptLanguage) { // Если нет только Accept-Language → не считаем ботом, но логируем error_log("[WARNING] Нет Accept-Language (IP: $ip)"); } // в) Проверка частоты запросов (только для не‑локальных IP) $localIPPattern = '/^(127\.|192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)/'; if (!preg_match($localIPPattern, $ip)) { // Читаем только последние 50 записей для оптимизации $logLines = @file($logFile, FILE_IGNORE_NEW_LINES); if ($logLines === false) { error_log("[ERROR] Не удалось прочитать лог-файл: $logFile"); } else { $recentLines = array_slice($logLines, -50); $recentFromIP = array_filter($recentLines, function($line) use ($ip) { return strpos($line, $ip) !== false && (time() - strtotime(substr($line, 0, 19))) < 10; // за последние 10 секунд }); if (count($recentFromIP) > 3) { // более 3 запросов за 10 секунд $isBot = true; error_log("[BOT] Слишком частые запросы с IP: $ip (".count($recentFromIP)." за 10 сек)"); } } } // г) Проверка пустого User‑Agent if (empty($userAgent)) { $isBot = true; error_log("[BOT] User‑Agent пуст"); } // 3. Записываем визит в лог $logEntry = date('Y-m-d H:i:s') . "\t" . $ip . "\t" . $os . "\t" . $browser . "\t" . ($isBot ? 'bot' : 'human') . "\n"; if (@file_put_contents($logFile, $logEntry, FILE_APPEND) === false) { error_log("[ERROR] Не удалось записать в лог-файл: $logFile"); } // 4. Обновляем счётчик (только для людей) if (!$isBot) { if (file_exists($counterFile)) { $visits = (int)file_get_contents($counterFile); $visits++; if (@file_put_contents($counterFile, $visits) === false) { error_log("[ERROR] Не удалось обновить счётчик: $counterFile"); $visits = 0; } } else { if (@file_put_contents($counterFile, 1) === false) { error_log("[ERROR] Не удалось создать счётчик: $counterFile"); $visits = 0; } else { $visits = 1; } } } else { // Если это бот, читаем текущее значение (но не увеличиваем) $visits = file_exists($counterFile) ? (int)file_get_contents($counterFile) : 0; } // 5. Выводим результат echo "<small><p>Просмотров: <b>" . $visits . "</b></p></small>"; // 6. Отладочная информация (временно, для диагностики) // Раскомментируйте ниже, чтобы увидеть детали /* echo "<pre>"; echo "IP: $ip\n"; echo "User-Agent: $userAgent\n"; echo "OS: $os\n"; echo "Browser: $browser\n"; echo "isBot: " . ($isBot ? 'да' : 'нет') . "\n"; echo "HTTP_ACEPT: " . ($hasAccept ? 'есть' : 'нет') . "\n"; echo "HTTP_ACEPT_LANGUAGE: " . ($hasAcceptLanguage ? 'есть' : 'нет') . "\n"; echo "</pre>"; */ ?>
В этой статье разберём рабочий PHP‑скрипт для подсчёта реальных просмотров страницы с фильтрацией ботов. Код не требует JavaScript и опирается на анализ HTTP‑запросов.
Что делает скрипт
- Собирает данные о посетителе (IP, User‑Agent, ОС, браузер).
- Фильтрует ботов по 4 критериям:
- подозрительные слова в User‑Agent;
- отсутствие обязательных HTTP‑заголовков;
- слишком частые запросы с одного IP;
- пустой User‑Agent.
- Записывает лог всех визитов в файл
visits_log.txt. - Обновляет счётчик реальных просмотров в файле
visits.txt. - Выводит число просмотров на страницу.
Структура кода
1. Настройка путей к файлам
$counterFile = ‘visits.txt’; // Счётчик реальных просмотров
$logFile = ‘visits_log.txt’; // Лог всех визитов (люди + боты)
Важно: файлы должны быть доступны для чтения/записи PHP.
2. Сбор данных о посетителе
$ip = $_SERVER[‘REMOTE_ADDR’] ?? ‘unknown’;
$userAgent = $_SERVER[‘HTTP_USER_AGENT’] ?? ‘unknown’;
$ip— IP‑адрес посетителя.$userAgent— строка с информацией о браузере и ОС.
3. Определение ОС и браузера
Функции getOS() и getBrowser() анализируют $userAgent и возвращают:
- ОС: Windows, MacOS, Linux, Android, iOS или Unknown.
- Браузер: Chrome, Firefox, Safari, Edge, Opera, Internet Explorer или Unknown.
Пример:
User-Agent: Mozilla/5.0 (X11; Linux x86_64) …
→ ОС: Linux, Браузер: Chrome
4. Фильтрация ботов ($isBot)
а) Проверка User‑Agent
$botPattern = ‘/(bot|crawler|…)(?!chrome|firefox|…)/i’;
if (preg_match($botPattern, $userAgent)) {
$isBot = true;
}
- Что делает: ищет слова типа
bot,crawler,spiderв User‑Agent. - Исключения: если после такого слова идёт
Chrome,Firefoxи т. п., визит не считается ботом. - Логирование: запись в
error.logпри совпадении.
б) Проверка HTTP‑заголовков
$hasAccept = isset($_SERVER[‘HTTP_ACEPT’]);
$hasAcceptLanguage = isset($_SERVER[‘HTTP_ACEPT_LANGUAGE’]);if (!$hasAccept && !$hasAcceptLanguage) {
$isBot = true; // Оба заголовка отсутствуют → бот
} elseif (!$hasAcceptLanguage) {
// Только Accept-Language отсутствует → предупреждение
}
- Почему важно: боты часто не отправляют эти заголовки.
- Гибкость: визит не блокируется, если хотя бы один заголовок есть.
в) Проверка частоты запросов
if (!preg_match($localIPPattern, $ip)) { // Не локальный IP
// Читаем последние 50 записей из лога
$recentFromIP = array_filter($logLines, function($line) use ($ip) {
return strpos($line, $ip) !== false &&
(time() — strtotime(substr($line, 0, 19))) < 10;
});
if (count($recentFromIP) > 3) {
$isBot = true; // >3 запросов за 10 сек → бот
}
}
- Для кого: только для внешних IP (локальные
127.0.0.1и др. исключены). - Оптимизация: анализируются только последние 50 записей.
- Критерий: более 3 запросов за 10 секунд → метка «бот».
г) Проверка пустого User‑Agent
if (empty($userAgent)) {
$isBot = true;
}
- Причина: реальные браузеры всегда отправляют User‑Agent.
5. Запись в лог
$logEntry = date(‘Y-m-d H:i:s’) . «\t» . $ip . «\t» . $os . «\t» . $browser . «\t» . ($isBot ? ‘bot’ : ‘human’) . «\n»;
file_put_contents($logFile, $logEntry, FILE_APPEND);
- Формат лога: дата, IP, ОС, браузер, статус (bot/human).
- Пример записи:
2026-01-28 07:52:51 127.0.0.1 Linux Chrome human
6. Обновление счётчика просмотров
if (!$isBot) {
// Увеличиваем счётчик на 1
$visits = (int)file_get_contents($counterFile) + 1;
file_put_contents($counterFile, $visits);
} else {
// Для ботов — только чтение текущего значения
$visits = file_exists($counterFile) ? (int)file_get_contents($counterFile) : 0;
}
- Только для людей: счётчик растёт лишь при
$isBot = false. - Обработка ошибок: если файл недоступен — логируется ошибка, счётчик = 0.
7. Вывод результата
echo «<small><p>Просмотров: <b>» . $visits . «</b></p></small>»;
- Где отображается: на странице, где подключён скрипт.
- Формат: «Просмотров: N».
8. Отладка (опционально)
/*
echo «<pre>»;
echo «IP: $ip\n»;
// … другие данные
echo «</pre>»;
*/
- Как использовать: раскомментировать блок для вывода деталей в браузере.
- Для чего: диагностика проблем (например, отсутствие заголовков).
Как установить
- Сохраните код в файл (например,
counter.php). - Создайте файлы
visits.txtиvisits_log.txtв той же директории. - Убедитесь, что PHP имеет права на запись в эти файлы:
chmod 644 visits.txt visits_log.txt
Подключите скрипт на нужной странице:
<?php include ‘counter.php’; ?>
Возможные улучшения
- Защита от накрутки:
- Добавлять IP в чёрный список после N ботовых запросов.
- Использовать сессии для отслеживания уникальных посетителей.
- Расширенная аналитика:
- Считать просмотры по дням/месяцам.
- Выводить топ‑браузеров/ОС.
- Безопасность:
- Ограничить доступ к
visits_log.txtчерез.htaccess. - Валидировать IP перед записью в лог.
- Ограничить доступ к
- Производительность:
- Для высоконагруженных сайтов использовать базу данных (MySQL, SQLite) вместо файлов.
Итоги
Плюсы скрипта:
- Не требует JavaScript.
- Фильтрует большинство ботов.
- Логирует все визиты для анализа.
- Простой в установке и настройке.
Когда подойдёт:
- Для личных блогов, портфолио, небольших сайтов.
- Если нужна базовая статистика без сложных систем (Google Analytics).
Ограничения:
- Может пропускать продвинутых ботов, имитирующих браузер.
- Для крупных проектов лучше использовать специализированные инструменты.

