Счётчик просмотров для одной страницы на php

В этой статье разберём рабочий 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‑запросов.

Что делает скрипт

  1. Собирает данные о посетителе (IP, User‑Agent, ОС, браузер).
  2. Фильтрует ботов по 4 критериям:
    • подозрительные слова в User‑Agent;
    • отсутствие обязательных HTTP‑заголовков;
    • слишком частые запросы с одного IP;
    • пустой User‑Agent.
  3. Записывает лог всех визитов в файл visits_log.txt.
  4. Обновляет счётчик реальных просмотров в файле visits.txt.
  5. Выводит число просмотров на страницу.

Структура кода

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;
}

  • Что делает: ищет слова типа botcrawlerspider в User‑Agent.
  • Исключения: если после такого слова идёт ChromeFirefox и т. п., визит не считается ботом.
  • Логирование: запись в 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>»;
*/

  • Как использовать: раскомментировать блок для вывода деталей в браузере.
  • Для чего: диагностика проблем (например, отсутствие заголовков).

Как установить

  1. Сохраните код в файл (например, counter.php).
  2. Создайте файлы visits.txt и visits_log.txt в той же директории.
  3. Убедитесь, что PHP имеет права на запись в эти файлы:

chmod 644 visits.txt visits_log.txt

Подключите скрипт на нужной странице:

<?php include ‘counter.php’; ?>

Возможные улучшения

  1. Защита от накрутки:
    • Добавлять IP в чёрный список после N ботовых запросов.
    • Использовать сессии для отслеживания уникальных посетителей.
  2. Расширенная аналитика:
    • Считать просмотры по дням/месяцам.
    • Выводить топ‑браузеров/ОС.
  3. Безопасность:
    • Ограничить доступ к visits_log.txt через .htaccess.
    • Валидировать IP перед записью в лог.
  4. Производительность:
    • Для высоконагруженных сайтов использовать базу данных (MySQL, SQLite) вместо файлов.

Итоги

Плюсы скрипта:

  • Не требует JavaScript.
  • Фильтрует большинство ботов.
  • Логирует все визиты для анализа.
  • Простой в установке и настройке.

Когда подойдёт:

  • Для личных блогов, портфолио, небольших сайтов.
  • Если нужна базовая статистика без сложных систем (Google Analytics).

Ограничения:

  • Может пропускать продвинутых ботов, имитирующих браузер.
  • Для крупных проектов лучше использовать специализированные инструменты.

Добавить комментарий

Войти с помощью: