byuik
24 March 2025

Как проверить посещаемость сайта ?
Можно разместить разные сервисы на подобие google analytics и ещё милион других .
Но я предлагаю сделать свою статистику.
📊 Возможности скрипта статистики посещений
Этот универсальный скрипт предоставляет следующие возможности:
При первом открытии скрипт создаст базу sqlite , для глубокого анализа есть "Админ-панель".
📌 Основная статистика (баннер)
- Сейчас онлайн
- Количество уникальных посетителей за последние 5 минут (исключая администратора)
- Новые посетители
- Количество новых пользователей за последние 5 минут
- Посещения за сегодня
- Уникальные посетители с 00:00 текущих суток
- Посещения за месяц
- Уникальные посетители с 1 числа текущего месяца
- Всего посещений
- Общее количество уникальных посещений за всё время
🔐 Административная панель
Доступна по клику на баннер (открывается в новой вкладке).
Функционал админки:
- Авторизация
- Пароль по умолчанию:
password
(можно изменить) - Пароль хранится в зашифрованном виде (используется
password_hash
)
- Пароль по умолчанию:
- Расширенная статистика
- IP за последние 15 минут
- Список всех IP-адресов и количество их посещений
- Повторяющиеся IP за день
- IP-адреса, которые посещали сайт более 1 раза сегодня
- Автоматическое определение IP администратора
- При первом входе в админку IP сохраняется и исключается из статистики
- IP за последние 15 минут
- Управление паролем
- Смена пароля админки (новый пароль также хранится в зашифрованном виде)
🛡️ Технические особенности
- Хранение данных
- Используется SQLite (файл
visitors.db
) - 3 таблицы:
visitors
(данные о посетителях, включая IP и отметку администратора)stats
(общая статистика)admin
(пароль и IP администратора)
- Используется SQLite (файл
- Защита данных
- IP администратора исключается из общей статистики
- Пароли хранятся в виде хешей (
password_hash
) - Нет уязвимостей к SQL-инъекциям (используются подготовленные запросы PDO)
- Автоматические сбросы
- Счетчик месячных посещений сбрасывается 1 числа каждого месяца
- Счетчик дневных посещений сбрасывается в 00:00
- Кросс-браузерность
- Баннер корректно отображается на любых устройствах
- Админ-панель работает во всех современных браузерах
⚙️ Как использовать?
- Разместите файл
visitor_counter.php
в корне сайта. Вставьте код для отображения баннера:
<iframe src="/visitor_counter.php" width="150" height="130" style="border: none;"></iframe>
- Для доступа к админке кликните на баннер (откроется в новой вкладке).
<?php
// Путь к файлу базы данных SQLite
$db_file = 'visitors.db';
// Создаем или открываем базу данных
try {
$db = new PDO("sqlite:$db_file");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Ошибка подключения к базе данных: " . $e->getMessage());
}
// Создаем таблицы, если они не существуют
$create_table_query = "
CREATE TABLE IF NOT EXISTS visitors (
id INTEGER PRIMARY KEY AUTOINCREMENT,
visitor_id TEXT NOT NULL UNIQUE,
first_visit_time INTEGER NOT NULL,
last_visit_time INTEGER NOT NULL,
ip_address TEXT NOT NULL,
is_admin INTEGER DEFAULT 0
);
CREATE TABLE IF NOT EXISTS stats (
id INTEGER PRIMARY KEY AUTOINCREMENT,
total_visits INTEGER DEFAULT 0,
monthly_visits INTEGER DEFAULT 0,
today_visits INTEGER DEFAULT 0,
current_month INTEGER DEFAULT 0,
current_year INTEGER DEFAULT 0
);
CREATE TABLE IF NOT EXISTS admin (
id INTEGER PRIMARY KEY AUTOINCREMENT,
password_hash TEXT NOT NULL,
admin_ip TEXT
);
";
$db->exec($create_table_query);
// Если таблица admin пуста, добавляем пароль по умолчанию (password)
$stmt = $db->query("SELECT COUNT(*) as count FROM admin");
if ($stmt->fetch()['count'] == 0) {
$default_password = 'password';
$password_hash = password_hash($default_password, PASSWORD_DEFAULT);
$db->exec("INSERT INTO admin (password_hash) VALUES ('$password_hash')");
}
// Получаем данные админа из базы
$admin_data = $db->query("SELECT password_hash, admin_ip FROM admin LIMIT 1")->fetch(PDO::FETCH_ASSOC);
$password_hash = $admin_data['password_hash'];
$admin_ip = $admin_data['admin_ip'];
// Обработка смены пароля
if (isset($_POST['change_password'])) {
$new_password = $_POST['new_password'];
if (!empty($new_password)) {
$new_hash = password_hash($new_password, PASSWORD_DEFAULT);
$db->exec("UPDATE admin SET password_hash = '$new_hash'");
$password_hash = $new_hash;
echo "<p style='color: green;'>Пароль успешно изменен!</p>";
} else {
echo "<p style='color: red;'>Пароль не может быть пустым!</p>";
}
}
// Проверка входа в админку
$is_admin = false;
if (isset($_POST['login'])) {
$input_password = $_POST['password'];
if (password_verify($input_password, $password_hash)) {
$is_admin = true;
// Запоминаем IP администратора при первом входе
if (empty($admin_ip)) {
$current_ip = $_SERVER['REMOTE_ADDR'];
$db->exec("UPDATE admin SET admin_ip = '$current_ip'");
$admin_ip = $current_ip;
// Помечаем текущего пользователя как администратора
$db->exec("UPDATE visitors SET is_admin = 1 WHERE ip_address = '$current_ip'");
}
} else {
echo "<p style='color: red;'>Неверный пароль!</p>";
}
}
// Получаем IP-адрес текущего пользователя
$current_ip = $_SERVER['REMOTE_ADDR'];
$is_current_admin = ($current_ip === $admin_ip);
// Текущее время и временные метки
$current_time = time();
$five_minutes_ago = $current_time - 300;
$fifteen_minutes_ago = $current_time - 900;
$current_month = date('n');
$current_year = date('Y');
$start_of_today = strtotime('today 00:00:00');
$start_of_month = strtotime('first day of this month 00:00:00');
// Обработка посещения
$is_new_visitor = true;
if (isset($_COOKIE['visitor_id'])) {
$visitor_id = $_COOKIE['visitor_id'];
$stmt = $db->prepare("SELECT * FROM visitors WHERE visitor_id = :visitor_id");
$stmt->execute([':visitor_id' => $visitor_id]);
if ($row = $stmt->fetch()) {
$is_new_visitor = false;
$db->prepare("UPDATE visitors SET last_visit_time = :last_visit_time WHERE visitor_id = :visitor_id")
->execute([':last_visit_time' => $current_time, ':visitor_id' => $visitor_id]);
}
} else {
$visitor_id = uniqid();
setcookie('visitor_id', $visitor_id, time() + (86400 * 30), "/");
}
if ($is_new_visitor) {
$is_admin_flag = $is_current_admin ? 1 : 0;
$db->prepare("INSERT INTO visitors (visitor_id, first_visit_time, last_visit_time, ip_address, is_admin) VALUES (:visitor_id, :first_visit_time, :last_visit_time, :ip_address, :is_admin)")
->execute([
':visitor_id' => $visitor_id,
':first_visit_time' => $current_time,
':last_visit_time' => $current_time,
':ip_address' => $current_ip,
':is_admin' => $is_admin_flag
]);
}
// Обновление статистики
$stats = $db->query("SELECT * FROM stats LIMIT 1")->fetch(PDO::FETCH_ASSOC);
if (!$stats) {
$db->exec("INSERT INTO stats (total_visits, monthly_visits, today_visits, current_month, current_year) VALUES (0, 0, 0, 0, 0)");
$stats = $db->query("SELECT * FROM stats LIMIT 1")->fetch(PDO::FETCH_ASSOC);
}
if ($stats['current_month'] != $current_month || $stats['current_year'] != $current_year) {
$db->exec("UPDATE stats SET monthly_visits = 0, current_month = $current_month, current_year = $current_year");
}
if ($is_new_visitor && !$is_current_admin) {
$db->exec("UPDATE stats SET total_visits = total_visits + 1, monthly_visits = monthly_visits + 1, today_visits = today_visits + 1");
}
// Получение статистики
$stats = $db->query("SELECT * FROM stats LIMIT 1")->fetch(PDO::FETCH_ASSOC);
$total_visits = $stats['total_visits'];
$monthly_visits = $stats['monthly_visits'];
$today_visits = $stats['today_visits'];
// Подсчет посещений (исключая администратора)
function getCount($db, $sql, $params) {
$stmt = $db->prepare($sql . " AND is_admin = 0");
$stmt->execute($params);
return $stmt->fetch()['count'];
}
$current_visits_last_5_minutes = getCount($db,
"SELECT COUNT(*) as count FROM visitors WHERE last_visit_time >= :time",
[':time' => $five_minutes_ago]
);
$new_visitors_last_5_minutes = getCount($db,
"SELECT COUNT(*) as count FROM visitors WHERE first_visit_time >= :time",
[':time' => $five_minutes_ago]
);
$today_visits = getCount($db,
"SELECT COUNT(*) as count FROM visitors WHERE last_visit_time >= :time",
[':time' => $start_of_today]
);
$monthly_visits = getCount($db,
"SELECT COUNT(*) as count FROM visitors WHERE last_visit_time >= :time",
[':time' => $start_of_month]
);
// Админ-панель
if (isset($_GET['admin'])) {
echo "<h2>Админ-панель</h2>";
if (!$is_admin) {
echo "<form method='post'>
<input type='password' name='password' placeholder='Введите пароль' required>
<button type='submit' name='login'>Войти</button>
</form>";
} else {
echo "<h3>Расширенная статистика</h3>";
echo "<p><strong>Ваш IP (админ):</strong> $admin_ip</p>";
// IP за последние 15 минут
$stmt = $db->prepare("SELECT ip_address, COUNT(*) as count FROM visitors WHERE last_visit_time >= :time AND is_admin = 0 GROUP BY ip_address");
$stmt->execute([':time' => $fifteen_minutes_ago]);
echo "<h4>IP за последние 15 минут:</h4><ul>";
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $ip) {
echo "<li>{$ip['ip_address']} ({$ip['count']})</li>";
}
echo "</ul>";
// Повторяющиеся IP
$stmt = $db->prepare("SELECT ip_address, COUNT(*) as count FROM visitors WHERE last_visit_time >= :time AND is_admin = 0 GROUP BY ip_address HAVING count > 1");
$stmt->execute([':time' => $start_of_today]);
echo "<h4>Повторные IP за день:</h4><ul>";
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $ip) {
echo "<li>{$ip['ip_address']} ({$ip['count']})</li>";
}
echo "</ul>";
// Смена пароля
echo "<h4>Смена пароля:</h4>
<form method='post'>
<input type='password' name='new_password' placeholder='Новый пароль' required>
<button type='submit' name='change_password'>Сменить</button>
</form>";
}
exit;
}
// Баннер (открывается в новой вкладке)
echo "<a href='?admin=1' target='_blank' style='text-decoration: none; color: inherit;'>";
echo "<div style='border: 1px solid #ccc; padding: 5px; width: 120px; font-size: 12px; text-align: center; background-color: #f9f9f9; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); font-family: Arial, sans-serif; color: #333;'>";
echo "<strong style='font-size: 14px; color: #555;'>Статистика</strong><br>";
echo "<div style='margin-top: 8px;'>";
echo "👥 Сейчас: <span style='color: #007BFF; font-weight: bold;'>$current_visits_last_5_minutes</span><br>";
echo "🆕 Новые: <span style='color: #28a745; font-weight: bold;'>$new_visitors_last_5_minutes</span><br>";
echo "📅 Сегодня: <span style='color: #ffc107; font-weight: bold;'>$today_visits</span><br>";
echo "📊 Месяц: <span style='color: #dc3545; font-weight: bold;'>$monthly_visits</span><br>";
echo "🌍 Всего: <span style='color: #6c757d; font-weight: bold;'>$total_visits</span>";
echo "</div></div></a>";
?>
Доработал админку , имеется гафик посещений и довлены поля для размещения гугл и подобных счетчиков.
В прочем тестируйте кому понравится.

<?php
// Путь к файлу базы данных SQLite
$db_file = 'visitors.db';
// Создаем или открываем базу данных
try {
$db = new PDO("sqlite:$db_file");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Ошибка подключения к базе данных: " . $e->getMessage());
}
// Создаем таблицы, если они не существуют
$create_table_query = "
CREATE TABLE IF NOT EXISTS visitors (
id INTEGER PRIMARY KEY AUTOINCREMENT,
visitor_id TEXT NOT NULL UNIQUE,
first_visit_time INTEGER NOT NULL,
last_visit_time INTEGER NOT NULL,
ip_address TEXT NOT NULL,
is_admin INTEGER DEFAULT 0
);
CREATE TABLE IF NOT EXISTS stats (
id INTEGER PRIMARY KEY AUTOINCREMENT,
total_visits INTEGER DEFAULT 0,
monthly_visits INTEGER DEFAULT 0,
today_visits INTEGER DEFAULT 0,
current_month INTEGER DEFAULT 0,
current_year INTEGER DEFAULT 0
);
CREATE TABLE IF NOT EXISTS admin (
id INTEGER PRIMARY KEY AUTOINCREMENT,
password_hash TEXT NOT NULL,
admin_ip TEXT
);
CREATE TABLE IF NOT EXISTS settings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
meta_title TEXT,
meta_description TEXT,
google_analytics TEXT
);
";
$db->exec($create_table_query);
// Проверяем и добавляем отсутствующие колонки в таблицу settings
try {
$columns = $db->query("PRAGMA table_info(settings)")->fetchAll(PDO::FETCH_ASSOC);
$existing_columns = array_column($columns, 'name');
$required_columns = ['meta_title', 'meta_description', 'google_analytics'];
foreach ($required_columns as $column) {
if (!in_array($column, $existing_columns)) {
$db->exec("ALTER TABLE settings ADD COLUMN $column TEXT");
}
}
} catch (PDOException $e) {
$db->exec("DROP TABLE IF EXISTS settings");
$db->exec("CREATE TABLE settings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
meta_title TEXT,
meta_description TEXT,
google_analytics TEXT
)");
}
// Если таблица admin пуста, добавляем пароль по умолчанию (password)
$stmt = $db->query("SELECT COUNT(*) as count FROM admin");
if ($stmt->fetch()['count'] == 0) {
$default_password = 'password';
$password_hash = password_hash($default_password, PASSWORD_DEFAULT);
$db->exec("INSERT INTO admin (password_hash) VALUES ('$password_hash')");
}
// Если таблица settings пуста, добавляем настройки по умолчанию
$stmt = $db->query("SELECT COUNT(*) as count FROM settings");
if ($stmt->fetch()['count'] == 0) {
$db->exec("INSERT INTO settings (meta_title, meta_description, google_analytics) VALUES ('Мой сайт', 'Описание моего сайта', '')");
}
// Получаем данные админа из базы
$admin_data = $db->query("SELECT password_hash, admin_ip FROM admin LIMIT 1")->fetch(PDO::FETCH_ASSOC);
$password_hash = $admin_data['password_hash'];
$admin_ip = $admin_data['admin_ip'];
// Получаем настройки сайта
$settings = $db->query("SELECT * FROM settings LIMIT 1")->fetch(PDO::FETCH_ASSOC);
$meta_title = $settings['meta_title'] ?? 'Мой сайт';
$meta_description = $settings['meta_description'] ?? 'Описание моего сайта';
$google_analytics = $settings['google_analytics'] ?? '';
// Обработка смены пароля
if (isset($_POST['change_password'])) {
$new_password = $_POST['new_password'];
if (!empty($new_password)) {
$new_hash = password_hash($new_password, PASSWORD_DEFAULT);
$db->exec("UPDATE admin SET password_hash = '$new_hash'");
$password_hash = $new_hash;
echo "<p style='color: green;'>Пароль успешно изменен!</p>";
} else {
echo "<p style='color: red;'>Пароль не может быть пустым!</p>";
}
}
// Обработка сохранения настроек
if (isset($_POST['save_settings'])) {
$new_meta_title = $_POST['meta_title'];
$new_meta_description = $_POST['meta_description'];
$new_google_analytics = $_POST['google_analytics'];
$stmt = $db->prepare("UPDATE settings SET meta_title = ?, meta_description = ?, google_analytics = ?");
$stmt->execute([$new_meta_title, $new_meta_description, $new_google_analytics]);
$meta_title = $new_meta_title;
$meta_description = $new_meta_description;
$google_analytics = $new_google_analytics;
echo "<p style='color: green;'>Настройки успешно сохранены!</p>";
}
// Проверка входа в админку
$is_admin = false;
if (isset($_POST['login'])) {
$input_password = $_POST['password'];
if (password_verify($input_password, $password_hash)) {
$is_admin = true;
$current_ip = $_SERVER['REMOTE_ADDR'];
$db->exec("UPDATE admin SET admin_ip = '$current_ip'");
if (!empty($admin_ip) && $admin_ip != $current_ip) {
$db->exec("UPDATE visitors SET is_admin = 0 WHERE ip_address = '$admin_ip'");
}
$db->exec("UPDATE visitors SET is_admin = 1 WHERE ip_address = '$current_ip'");
$admin_ip = $current_ip;
} else {
echo "<p style='color: red;'>Неверный пароль!</p>";
}
}
// Получаем IP-адрес текущего пользователя
$current_ip = $_SERVER['REMOTE_ADDR'];
$is_current_admin = ($current_ip === $admin_ip);
// Текущее время и временные метки
$current_time = time();
$five_minutes_ago = $current_time - 300;
$fifteen_minutes_ago = $current_time - 900;
$current_month = date('n');
$current_year = date('Y');
$start_of_today = strtotime('today 00:00:00');
$start_of_month = strtotime('first day of this month 00:00:00');
// Обработка посещения
$is_new_visitor = true;
if (isset($_COOKIE['visitor_id'])) {
$visitor_id = $_COOKIE['visitor_id'];
$stmt = $db->prepare("SELECT * FROM visitors WHERE visitor_id = :visitor_id");
$stmt->execute([':visitor_id' => $visitor_id]);
if ($row = $stmt->fetch()) {
$is_new_visitor = false;
$db->prepare("UPDATE visitors SET last_visit_time = :last_visit_time WHERE visitor_id = :visitor_id")
->execute([':last_visit_time' => $current_time, ':visitor_id' => $visitor_id]);
}
} else {
$visitor_id = uniqid();
setcookie('visitor_id', $visitor_id, time() + (86400 * 30), "/");
}
if ($is_new_visitor) {
$is_admin_flag = $is_current_admin ? 1 : 0;
$db->prepare("INSERT INTO visitors (visitor_id, first_visit_time, last_visit_time, ip_address, is_admin) VALUES (:visitor_id, :first_visit_time, :last_visit_time, :ip_address, :is_admin)")
->execute([
':visitor_id' => $visitor_id,
':first_visit_time' => $current_time,
':last_visit_time' => $current_time,
':ip_address' => $current_ip,
':is_admin' => $is_admin_flag
]);
}
// Обновление статистики
$stats = $db->query("SELECT * FROM stats LIMIT 1")->fetch(PDO::FETCH_ASSOC);
if (!$stats) {
$db->exec("INSERT INTO stats (total_visits, monthly_visits, today_visits, current_month, current_year) VALUES (0, 0, 0, 0, 0)");
$stats = $db->query("SELECT * FROM stats LIMIT 1")->fetch(PDO::FETCH_ASSOC);
}
if ($stats['current_month'] != $current_month || $stats['current_year'] != $current_year) {
$db->exec("UPDATE stats SET monthly_visits = 0, current_month = $current_month, current_year = $current_year");
}
if ($is_new_visitor && !$is_current_admin) {
$db->exec("UPDATE stats SET total_visits = total_visits + 1, monthly_visits = monthly_visits + 1, today_visits = today_visits + 1");
}
// Получение статистики
$stats = $db->query("SELECT * FROM stats LIMIT 1")->fetch(PDO::FETCH_ASSOC);
$total_visits = $stats['total_visits'];
$monthly_visits = $stats['monthly_visits'];
$today_visits = $stats['today_visits'];
// Подсчет посещений (исключая администратора)
function getCount($db, $sql, $params) {
$stmt = $db->prepare($sql . " AND is_admin = 0");
$stmt->execute($params);
return $stmt->fetch()['count'];
}
$current_visits_last_5_minutes = getCount($db,
"SELECT COUNT(*) as count FROM visitors WHERE last_visit_time >= :time",
[':time' => $five_minutes_ago]
);
$new_visitors_last_5_minutes = getCount($db,
"SELECT COUNT(*) as count FROM visitors WHERE first_visit_time >= :time",
[':time' => $five_minutes_ago]
);
$today_visits = getCount($db,
"SELECT COUNT(*) as count FROM visitors WHERE last_visit_time >= :time",
[':time' => $start_of_today]
);
$monthly_visits = getCount($db,
"SELECT COUNT(*) as count FROM visitors WHERE last_visit_time >= :time",
[':time' => $start_of_month]
);
// Функция для получения данных для графика посещений
function getVisitsByDay($db, $days = 30) {
$result = [];
for ($i = 0; $i < $days; $i++) {
$day_start = strtotime("-$i days 00:00:00");
$day_end = strtotime("-$i days 23:59:59");
$day_label = date("d.m", $day_start);
$stmt = $db->prepare("SELECT COUNT(*) as count FROM visitors WHERE last_visit_time BETWEEN :start AND :end AND is_admin = 0");
$stmt->execute([':start' => $day_start, ':end' => $day_end]);
$count = $stmt->fetch()['count'];
$result[$day_label] = $count;
}
return array_reverse($result);
}
// Функция для получения данных для графика уникальных посещений
function getUniqueVisitsByDay($db, $days = 30) {
$result = [];
for ($i = 0; $i < $days; $i++) {
$day_start = strtotime("-$i days 00:00:00");
$day_end = strtotime("-$i days 23:59:59");
$day_label = date("d.m", $day_start);
$stmt = $db->prepare("SELECT COUNT(DISTINCT ip_address) as count FROM visitors WHERE last_visit_time BETWEEN :start AND :end AND is_admin = 0");
$stmt->execute([':start' => $day_start, ':end' => $day_end]);
$count = $stmt->fetch()['count'];
$result[$day_label] = $count;
}
return array_reverse($result);
}
// Админ-панель
if (isset($_GET['admin'])) {
$visits_data = getVisitsByDay($db, 30);
$unique_visits_data = getUniqueVisitsByDay($db, 30);
$chart_labels = json_encode(array_keys($visits_data));
$chart_values = json_encode(array_values($visits_data));
$unique_chart_values = json_encode(array_values($unique_visits_data));
echo "<!DOCTYPE html>
<html>
<head>
<title>Админ-панель</title>
<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>
<script>
function copyIP(ip) {
const el = document.createElement('textarea');
el.value = ip;
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
alert('IP скопирован: ' + ip);
}
</script>
<style>
.ip-item {
cursor: pointer;
padding: 5px;
margin: 2px;
background: #f0f0f0;
border-radius: 3px;
}
.ip-item:hover {
background: #e0e0e0;
}
.chart-container {
width: 100%;
max-width: 800px;
margin: 20px auto;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
margin-bottom: 20px;
}
.stat-box {
background: #f8f9fa;
padding: 15px;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.settings-form {
margin: 20px 0;
padding: 20px;
background: #f8f9fa;
border-radius: 5px;
}
.settings-form textarea {
width: 100%;
min-height: 100px;
}
.charts-container {
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: center;
}
.chart-wrapper {
flex: 1;
min-width: 300px;
max-width: 800px;
}
</style>
</head>
<body>";
echo "<h2>Админ-панель</h2>";
if (!$is_admin) {
echo "<form method='post'>
<input type='password' name='password' placeholder='Введите пароль' required>
<button type='submit' name='login'>Войти</button>
</form>";
} else {
echo "<div class='stats-grid'>
<div class='stat-box'>
<h3>Общая статистика</h3>
<p><strong>Всего посещений:</strong> $total_visits</p>
<p><strong>За месяц:</strong> $monthly_visits</p>
<p><strong>За сегодня:</strong> $today_visits</p>
</div>
<div class='stat-box'>
<h3>Текущая активность</h3>
<p><strong>Последние 5 минут:</strong> $current_visits_last_5_minutes</p>
<p><strong>Новые посетители (5 мин):</strong> $new_visitors_last_5_minutes</p>
<p><strong>Ваш IP:</strong> $current_ip</p>
</div>
</div>";
// Графики посещений
echo "<div class='charts-container'>
<div class='chart-wrapper'>
<h3>Посещения за последние 30 дней</h3>
<div class='chart-container'>
<canvas id='visitsChart'></canvas>
</div>
</div>
<div class='chart-wrapper'>
<h3>Уникальные посещения за последние 30 дней</h3>
<div class='chart-container'>
<canvas id='uniqueVisitsChart'></canvas>
</div>
</div>
</div>
<script>
const ctx = document.getElementById('visitsChart').getContext('2d');
const visitsChart = new Chart(ctx, {
type: 'bar',
data: {
labels: $chart_labels,
datasets: [{
label: 'Все посещения',
data: $chart_values,
backgroundColor: 'rgba(54, 162, 235, 0.5)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true,
ticks: {
stepSize: 1
}
}
}
}
});
const uniqueCtx = document.getElementById('uniqueVisitsChart').getContext('2d');
const uniqueVisitsChart = new Chart(uniqueCtx, {
type: 'bar',
data: {
labels: $chart_labels,
datasets: [{
label: 'Уникальные посещения',
data: $unique_chart_values,
backgroundColor: 'rgba(75, 192, 192, 0.5)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 1
}]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true,
ticks: {
stepSize: 1
}
}
}
}
});
</script>";
// Форма настроек
echo "<div class='settings-form'>
<h3>Настройки сайта</h3>
<form method='post'>
<div>
<label>Заголовок сайта (meta title):</label><br>
<input type='text' name='meta_title' value='" . htmlspecialchars($meta_title) . "' style='width: 100%'>
</div>
<div>
<label>Описание сайта (meta description):</label><br>
<textarea name='meta_description'>" . htmlspecialchars($meta_description) . "</textarea>
</div>
<div>
<label>Код Google Analytics:</label><br>
<textarea name='google_analytics'>" . htmlspecialchars($google_analytics) . "</textarea>
</div>
<button type='submit' name='save_settings'>Сохранить настройки</button>
</form>
</div>";
// IP за последние 15 минут
$stmt = $db->prepare("SELECT ip_address, COUNT(*) as count FROM visitors WHERE last_visit_time >= :time AND is_admin = 0 GROUP BY ip_address");
$stmt->execute([':time' => $fifteen_minutes_ago]);
echo "<h4>IP за последние 15 минут:</h4><div>";
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $ip) {
echo "<div class='ip-item' onclick='copyIP(\"{$ip['ip_address']}\")'>{$ip['ip_address']} (посещений: {$ip['count']})</div>";
}
echo "</div>";
// Повторяющиеся IP за день
$stmt = $db->prepare("SELECT ip_address, COUNT(*) as count FROM visitors WHERE last_visit_time >= :time AND is_admin = 0 GROUP BY ip_address HAVING count > 1");
$stmt->execute([':time' => $start_of_today]);
echo "<h4>Повторные IP за день (кликните для копирования):</h4><div>";
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $ip) {
echo "<div class='ip-item' onclick='copyIP(\"{$ip['ip_address']}\")'>{$ip['ip_address']} (посещений: {$ip['count']})</div>";
}
echo "</div>";
// Смена пароля
echo "<h4>Управление доступом</h4>
<form method='post'>
<input type='password' name='new_password' placeholder='Новый пароль' required>
<button type='submit' name='change_password'>Сменить пароль</button>
</form>";
}
echo "</body></html>";
exit;
}
// Основная страница (внешний интерфейс)
echo "<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>" . htmlspecialchars($meta_title) . "</title>
<meta name='description' content='" . htmlspecialchars($meta_description) . "'>";
if (!empty($google_analytics)) {
echo $google_analytics;
}
echo "</head>
<body>
<!-- Ваш контент сайта здесь -->
<!-- Баннер статистики (открывается в новой вкладке) -->
<a href='?admin=1' target='_blank' style='text-decoration: none; color: inherit;'>
<div style='border: 1px solid #ccc; padding: 5px; width: 120px; font-size: 12px; text-align: center; background-color: #f9f9f9; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); font-family: Arial, sans-serif; color: #333;'>
<strong style='font-size: 14px; color: #555;'>Статистика</strong><br>
<div style='margin-top: 8px;'>
👥 Сейчас: <span style='color: #007BFF; font-weight: bold;'>$current_visits_last_5_minutes</span><br>
🆕 Новые: <span style='color: #28a745; font-weight: bold;'>$new_visitors_last_5_minutes</span><br>
📅 Сегодня: <span style='color: #ffc107; font-weight: bold;'>$today_visits</span><br>
📊 Месяц: <span style='color: #dc3545; font-weight: bold;'>$monthly_visits</span><br>
🌍 Всего: <span style='color: #6c757d; font-weight: bold;'>$total_visits</span>
</div>
</div>
</a>
</body>
</html>";
?>
Теги
- Войдите или зарегистрируйтесь, чтобы оставлять комментарии