• Шаблоны для вашего сайта
  • Сделать сайт
  • Реклама
  • Berry CSS
  • Albireo Framework
  • Бесплатный HTML-курс
  • Telegram-канал
  • Обратная связь
MaxSite.org
О создании сайтов и не только
Создание сайтов под ключ →
Вход
×
или зарегистрироваться

Создаем статистику для сайта своими руками

Albireo Framework, SQLПросмотров: 762Комментарии: 017 февраля 2022 г.

Сегодня я расскажу как создать статистику для своего сайта на Albireo. Для хранения статистики будет использоваться база SQLite. Я покажу базовый пример, который вы сможете расширить под свою задачу. Лично мне нужна была статистика по страницам с группировкой по дате (посуточно), поэтому мой вариант выглядит вот так.

Общая схема работы

В момент загрузки любой страницы, выполняется код, который вносит в базу текущий адрес и дату. При желании вы можете также сохранять IP, браузер и любые другие параметры из $_SERVER, например referer, чтобы узнать откуда был переход. То есть в базе можно хранить любые данные.

Для просмотра статистики делается отдельная страница (произвольно), где формируется выборка из базы. У меня стоит группировка по датам и адресам, но если её убрать, то можно посмотреть любой URL. Если нужно сразу несколько отчётов, то можно сделать ещё одну страницу, где сформировать нужную выборку.

Поскольку данных будет много, то должна быть пагинация страниц. У нас это простой get-параметр вида адрес?page=N, где N — номер страницы пагинации.

Сбор статистики

Поскольку статистику нужно собирать для всех страниц, то код разместим в отдельном файле: albireo-data/my/stat.php и подключим в конфигурации: albireo-data/config/config.php в ключе functions:

return [
	...
    // файл для всех страниц
    'functions' => DATA_DIR . 'my/stat.php',
];

Albireo этот файл подключает через обычный require, поэтому в нём можно разместить как отдельную функцию, или сразу нужный код сбора статистики.

Файл stat.php

Вначале проверяем, что у нас не 404-страница, поскольку нет смысла их отслеживать. После этого мы получаем данные текущей страницы. Это массив и в нём мы смотрим ключ stat, если он равен «-», то это значит, что статистику для страницы сохранять не нужно.

После этого определяем текущий URL относительно корня сайта. Если адрес пустой, значит это главная, вместо этого будем использовать символ «/».

Теперь у нас есть возможность внести данные в базу. Для этого создаём PDO-соединение и выполняем запрос по созданию таблицы с проверкой, что её нет.

В конце просто добавляем данные с помощью SQL.

Вот полный код файла с комментариями.

<?php if (!defined('BASE_DIR')) exit('No direct script access allowed');

if (getVal('is404', false)) return; // не учитываем 404-страницы

$pageData = getVal('pageData'); // данные текущей страницы 

if (isset($pageData['stat']) and $pageData['stat'] == '-') return; // если статистика отключена

$currentUrl = getVal('currentUrl');
$url = $currentUrl['url']; // текущий url

if ($url === '') $url = '/'; // главная
    
$pdo = Pdo\PdoConnect::getInstance(); // PDO-подключение

$db = $pdo->connect([
        'dsn' => 'sqlite:' . DATA_DIR . 'storage' . DIRECTORY_SEPARATOR . 'stat.sqlite'
    ]);

if (empty($db)) {
    return; // выходим, поскольку нет возможности работы с базой
} 

// создаём таблицу, если её ещё нет
Pdo\PdoQuery::query($db, "
CREATE TABLE IF NOT EXISTS stat (
   id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
   date TEXT NOT NULL DEFAULT '',
   url TEXT NOT NULL DEFAULT ''
);
");

// добавляем данные
Pdo\PdoQuery::insert($db,  'stat', [
    'date' => date("Y-m-d"),
    'url' => $url,
]);

# end of file

Обратите внимание на размещение sqlite-файла в каталоге storage. Это стандартное размещение для Albireo, но если по какой-то причине возникает ошибка, то возможно у этого каталога нет прав на запись. Вручную укажите «777».

Пробуем обновить страницы сайта, должен появиться файл stat.sqlite. Статистика собирается, подумаем как её вывести.

Вывод статистики

Для вывода будем использовать любую обычную страницу Albireo. Я разместил её по адресу stat. Параметры страницы у меня такие:

title: Статистика
description: Статистика сайта
slug: stat
sitemap: -
stat: -
head[]: <meta name="robots" content="noindex, nofollow">

Ключом sitemap мы отключаем добавление страницы в xml-карту сайта. Ключ stat отключаем сбор статистики этой страницы. А для того, чтобы страница не индексировалась поисковиками прописываем «noindex» для секции HEAD.

Вначале нужно получить доступ к базе данных.

$pdo = Pdo\PdoConnect::getInstance();

$db = $pdo->connect([
        'dsn' => 'sqlite:' . DATA_DIR . 'storage' . DIRECTORY_SEPARATOR . 'stat.sqlite'
    ]);

if (empty($db)) {
    echo '<div class="t-red600 t-center mar10">Ошибка соединения с БД</div>';
    return; // выходим, поскольку нет возможности работы с базой
}

Получить выборку из базы мы должны с помощью пагинации вида адрес?page=7. То есть в итоговом SQL-запросе будут использоваться LIMIT и OFFSET. Чтобы их корректно сформировать нам потребуется узнать

  • текущую страницу пагинации,
  • число записей на одну страницу пагинации,
  • общее количество записей в таблице.

Текущая пагинация у нас хранится в get-параметре page — получим его из данных страницы:

$currentUrl = getVal('currentUrl'); // текущий адрес
$current = (int) ($currentUrl['queryData']['page'] ?? 1); // текущая страница пагинации

if ($current < 1) $current = 1; // исправим, если нужно

Количество записей на страницу зададим жестко, например 40:

$limit = 40; // записей на одну страницу пагинации

Теперь нам нужно определить общее число записей в таблице, как будто бы мы не используем LIMIT и OFFSET. Проблема в том, что мы будем использовать sql-запрос с группировкой записей, поэтому мы получим не всего-всего записей в таблице, а именно сгруппированные записи. Чтобы было понятно, давайте рассмотрим sql-запрос с LIMIT и OFFSET.

$rows = Pdo\PdoQuery::fetchAll($db, '
   SELECT date, url, count(url) as count 
   FROM stat 
   GROUP BY date, url 
   ORDER BY date DESC, count DESC LIMIT :limit OFFSET :offset', 
   [
   	  ':limit' => $pag['limit'], 
   	  ':offset' => $pag['offset']
   ]);

Обратите внимание, что записи группируются по дате и URL — это позволяет сделать подсчёт количества посещений данного URL по дате. Число строк такого запроса будет меньше, чем обычным

$rows = Pdo\PdoQuery::fetchAll($db, 'SELECT * FROM stat');

Поэтому при подсчёте данных для пагинации, нам нужно узнать количество строк с учётом точно такой же группировки. Поэтому мы будем использовать основной sql-запрос, только уберём получение ненужных данных:

$allRows = Pdo\PdoQuery::fetchAll($db, 'SELECT date, url, count(url) as count FROM stat GROUP BY date, url');

От $allRows нам нужно только количество записей. Теперь мы можем получить массив пагинации:

$pag = Pdo\PdoQuery::getPagination($db, 'stat', $limit, $current, count($allRows)); // массив данных

И используем их в основном запросе (продублирую код):

$rows = Pdo\PdoQuery::fetchAll($db, 'SELECT date, url, count(url) as count FROM stat GROUP BY date, url ORDER BY date DESC, count DESC LIMIT :limit OFFSET :offset', [':limit' => $pag['limit'], ':offset' => $pag['offset']]);

Теперь в массиве $rows данные для вывода. Вы можете написать свой цикл обхода, я же использую табличный вывод:

echo Pdo\PdoQuery::outTableRows($rows);

Естественно, может потребоваться указать какое-то своё оформление. Поэтому обрамляющий HTML будет у вас свой.

Вывод пагинации

Все данные для пагинации у нас в массиве $pag. По сути пагинация — это блок ссылок на все доступные страницы. Поэтому можно их вывести в простом цикле for. Если это первая страница, то можно get-параметр не указывать. Также, если это текущая страница пагинации, то можно её оформить не ссылкой, а элементом SPAN. Ну и само оформление может быть произвольным.

// блок ссылок для пагинации
if ($pag['max'] > 1) {
	echo '<div class="mar30-tb">';

	for ($i = 1; $i <= $pag['max']; $i++) {
		if ($i > 1)
			$queryUrl = $currentUrl['urlFull'] . '?page=' . $i;
		else 
			$queryUrl = $currentUrl['urlFull'];

		if ($i == $current)
			echo '<span class="b-inline pad10-rl pad5-tb mar5-r mar10-b bg-teal600 t-white" style="cursor: default">' . $i . '</span>';		
		else			
			echo '<a class="b-inline pad10-rl pad5-tb mar5-r mar10-b hover-no-underline bg-teal100 hover-bg-teal700 hover-t-teal50" href="' . $queryUrl . '">' . $i . '</a> ';	
	}

	echo '</div>';
}

Вообще вариантов пагинации может быть множество. Если страниц будет очень много, то возможно более удобным будет сделать выпадающий SELECT с номером страницы. Для перехода можно прицепить несложный js-скрипт. Или сделать только две ссылки «Назад-Вперёд». Во всех случаях информации из $pag будет достаточно.


Создание сайтов (Украина) →
#НетВойне
Сравнение IDE для PHP - 2022
twitter.com facebook.com
Другие записи сайта
Небольшое интервью
Небольшое интервью
Magic Mail Monitor - всегда на связи!
Magic Mail Monitor - всегда на связи!
Отправка произвольной формы на AJAX без перезагрузки страницы
Отправка произвольной формы на AJAX без перезагрузки страницы
4t Tray Minimizer
4t Tray Minimizer
Шаблоны проектирования для PHP
Шаблоны проектирования для PHP
Блогу 2 года
Блогу 2 года
Оставьте комментарий!

Комментарий будет опубликован после проверки. Вы соглашаетесь с правилами сайта.

(обязательно)

Навигация
  • Шаблоны для MaxSite CMS 22
  • jQuery и JavaScript 6
  • Java и Android 5
  • PHP/ООП 25
  • SQL 17
  • Albireo Framework 11
  • Berry CSS 7
  • CSS, HTML, LESS, SASS 23
  • PHP 37
  • Тайм-менеджмент 9
  • Софт 37
  • SEO 13
  • Git. GitHub 3
  • CodeIgniter 5
  • Landing Page 3
  • Alpine.js 14
  • Фильмы 2
  • Дневник 55

Вот здесь можно заказать создание сайта, шаблона или лендинга. Также вы можете выбрать готовые шаблоны для MaxSite CMS по небольшой цене. Также можно купить отдельные модули, компоненты для вашего сайта.

MaxSite.org
Как создать свой сайт

Услуги по созданию сайтов, блогов, лендингов
Обратная связь • Реклама на сайте
Карта сайта
Мои проекты
  • Шаблоны для вашего сайта
  • Заказать создание сайта
  • MaxSite CMS
  • Berry CSS (CSS Utilities)
  • Albireo Framework
  • UniCSS (Universal Atomic CSS)
  • Landing Page Framework
  • Бесплатные НТML-курсы
Ссылки
  • Telegram-канал
  • Github
  • Twitter
  • Telegram-бот
  • RSS
© MaxSite.org, 2006-2022. Работает на MaxSite CMS | Время: 0.2578 | SQL: 20 | Память: 4.61MB | Вход