87 (+1)

Counter@PHP

Использование счетчиков для анализа посещаемости сайта
Общие принципы функционирования и типы счетчиков
Создание сложных текстовых и графических счетчиков

Поиск по сайтуДля желающих написать письмоПослать ссылку другуВерсия для распечатки




Часть II

Количество просмотров за сегодня

Общий счетчик удобен для оценки интегральной посещаемости странички, но как узнать, сколько раз страничка была просмотрена сегодня? Давайте модифицируем счетчик таким образом, чтобы поддерживалось два счетчика - общий и количество просмотров за сегодня. При этом алгоритм работы такого счетчика будет более сложный:

  1. Прочитать текущее содержимое счетчиков;
  2. Увеличить текущее содержимое "общего счетчика" на единицу;
  3. Проверить, наступил ли уже завтрашний день? Если нет, то увеличить текущее содержимое "счетчика за сегодня" на единицу. Если да, то установить "счетчик за сегодня" равным единице;
  4. Сохранить обновленное содержимое счетчиков;
  5. Вывести на печать обновленное значение счетчиков.

После прочтения алгоритма у вас может возникнуть вопрос - а как узнать, что наступил уже завтрашний день? А сделаем мы это следующим образом - одновременно с увеличением текущего содержимого счетчика мы будем сохранять также и дату последнего обращения к страничке. Это позволит нам определить факт наступления завтра простым сравнением даты последнего обращения к страничке и текущей даты.

Работа с датами в PHP


Для работы с датами в PHP существует целый ряд специализированных функций. Нас сейчас интересует только одна, которая возвращает текущую дату, а именно функция date(). В качестве аргумента в функцию передается текстовая строка, определяющая формат получаемой даты. Типичный запрос выглядит следующим образом:

$current_date = date("Y-m-d H:i:s");

В результате выполнения этой строки переменной $current_date будет присвоена текстовая строка, определяющая текущую дату и время. Если мы выведем эту переменную на печать, то увидим что-то типа следующего:

2006-02-04 15:32:07

Обратите внимание, что ее формат соответствует заданному нами, только буквы были заменены соответствующими значениями. Ниже я привожу список наиболее часто используемых букв и что они обозначают. Учтите, что регистр имеет значение. Итак:

  • d - день в виде 2-значного числа в формате с лидирующим нулем (01 - 31)
  • j - день в виде числа (1-31)
  • m - месяц в виде 2-значного числа в формате с лидирующим нулем (01 - 12)
  • n - месяц в виде числа (1-12)
  • y - год в формате двух последних цифр года (например, "04")
  • Y - год в полном 4-значном формате (например, "2004")
  • w - день недели (причем, 0 - это воскресенье, 1 - понедельник, 2 - вторник,.. 6 - суббота)
  • H - час в 24-часовом формате в виде 2-значного числа с лидирующим нулем (00 - 23)
  • G - час в 24-часовом формате без лидирующего нуля (0 - 23)
  • i - минуты (00 - 59)
  • s - секунды (00 - 59)

Полный список всех возможных кодов для форматирования даты Вы можете посмотреть в справочнике по функциям PHP

В отличие от ранее описанного простого счетчика, который хранит только одно значение, сейчас нам потребуется хранить целых три переменных. К общему счетчику посещений добавятся "счетчик за сегодня" и дата последнего просмотра странички. Вопрос - а как же сохранить эти переменные в файле? Ведь до сих пор мы сохраняли и читали только одно значение. Ответ будет следующим - нам необходимо упаковать несколько значений в одну строку, которую мы уже и будем сохранять в файле. А при чтении будем делать обратную операцию - распаковку строки.


Упаковка и распаковка данных



Для упаковки и распаковки переменных в строку в PHP существует пара удобных функций, предназначенных для этой цели. Они называются implode() и explode(). Первая служит для упаковки и в качестве исходных данных принимает массив (это значит, что предварительно нам придется преобразовать данные для упаковки в массив), а вторая распаковывает строку, возвращая результат в виде массива.

Предположим, что все необходимые параметры текущего значения счетчика нам уже известны, и тогда код для их упаковки в строку будет выглядеть следующим образом:

<?

// Определяем текущую дату
$current_date = date("Y-m-d");

// Формируем массив с параметрами счетчика
$counter = array(
    "total" =>  10,
    "today" =>  7,
    "date"  =>  $current_date
)

// Упаковываем данные из массива в строку
$string = implode(" | ", $counter);

?>

В примере я первой же командой рассчитал текущую дату, а далее сформировал вручную массив с параметрами счетчика. При этом значения счетчиков я взял произвольными (когда начнем писать работающий счетчик, то заменим их реальными значениями).

Обратите внимание, что в функции implode() в качестве первого параметра указывается т.н. разделитель - последовательность символов, которая будет разделять данные при "склеивании" их в одну строку. Я использовал последовательность символов " | " (пробел - вертикальная черта - пробел), т.к. она мне кажется наиболее удобной для чтения. В общем случае вы можете использовать любой другой символ или последовательность символов в качестве разделителя. Главное, чтобы он был уникальным и не встречался в данных, предназначенных для упаковки, т.к. в противном случае возникнут ошибки при распаковке, связанные с невозможностью корректно определить границы данных. В результате исполнения данного кода переменной $string будет присвоена следующая строка:

10 | 7 | 2006-02-04

Именно ее вы сможете увидеть в файле "counter.txt", после того как запустите данный скрипт (мы его еще, правда, не написали, но к концу статьи он наверняка уже будет работать).

Массивы в PHP


На самом деле в PHP используются не обычные массивы, а так называемые ассоциативные (другое название таких массивов - хеши). В отличие от классического массива, где доступ к нужной переменной осуществляется при помощи цифрового индекса, причем индекс начинается с нуля или единицы, в ассоциативных массивах в качестве индекса может выступать любая строка или число. Эта строка будет называться ключом, и ей будет сопоставлено определенное значение. Такая организация очень удобна. Особенно при работе со связанными данными. Предположим, что нам необходимо сохранить некую информацию о пользователе: его имя, фамилию, электронный адрес и город. С использованием ассоциативного массива это можно сделать следующим образом:

$user = array(
    "firstname" => "Вася",
    "lastname" => "Петров",
    "email" => "vasya@petrov.ru",
    "city" => "Санкт-Петербург"
);

Для задания параметров массива я использовал ключевое слово array(), указав в качестве параметров пары ключ-значение, разделенные запятой. Индексный ключ от значения отделяется специальной конструкцией =>. Удобнее всего писать именно так, как показано выше, - по одной переменной на строчке со сдвигом вправо. Теперь индексу с именем "firstname" сопоставлено значение "Вася", а индексу с именем "lastname" сопоставлено значение "Петров" и т.д.

Для того чтобы обратиться к конкретной переменной внутри ассоциативного массива, необходимо после имени массива, в квадратных скобках, указать значение ключа:

echo $user["firstname"]; // Напечатает слово "Вася"
echo $user["email"]; // Напечатает электронный адрес "vasya@petrov.ru"

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

Теперь разберемся с вопросом распаковки параметров нашего счетчика из строки. Будем считать, что она уже считана и нам необходимо извлечь из нее значения счетчика и вывести их на печать. Код, отвечающий за эту часть, будет выглядеть следующим образом:

<?

// Строка, хранящая параметры счетчика
$string = "10 | 7 | 2006-02-04";

// Извлекаем параметры счетчика из строки во временный массив
$temp_counter = explode(" | ", $string);

// Формируем ассоциативный массив с параметрами счетчика
$counter = array(
    "total" => $temp_counter[0],
    "today" => $temp_counter[1],
    "date"  => $temp_counter[2]
);
    
// Выводим значения счетчиков на печать
echo "Количество просмотров страницы: ".$counter["total"]." (+".$counter["today"].")";

?>

Как видите, функция explode() по синтаксису совпадает с implode(), и первым параметром передается разделитель, а вторым - строка для распаковки. В результате мы получаем ассоциативный массив с необходимыми данными. Последней строкой этого кода на печать выводится значение счетчиков. Я сделал более сложный вывод счетчика, чем в предыдущем варианте скрипта, за счет комбинирования текста и переменных, чтобы повысить удобство восприятия. На страничке это будет выглядеть вот так:

Количество просмотров страницы: 10 (+7)

Увеличение значений счетчиков



Осталось разобраться с вопросом увеличения значений счетчиков. Как мы уже договорились ранее, в файле, кроме счетчика, хранится и дата последнего доступа, поэтому нам нужно лишь сравнить ее с текущей датой, чтобы принять решение об увеличении "счетчика за сегодня". Предположим, что строка с информацией о счетчике уже считана и распакована в ассоциативный массив, тогда код увеличения счетчиков будет выглядеть следующим образом:

<?

// Определяем текущую дату
$current_date = date("Y-m-d");

...

// Увеличиваем на единицу общий счетчик
$counter["total"]++;

// Проверяем, наступило ли завтра
if ($counter["date"] != $current_date) {
	
    // Сбрасываем счетчик за сегодня
    $counter["today"] = 0;
}

// Увеличиваем на единицу счетчик за сегодня
$counter["today"]++;

// Обновляем дату последнего просмотра
$counter["date"] = $current_date;

?>

В вышеприведенном коде я не стал увеличивать значение "счетчика за сегодня", а наоборот, я его обнуляю в том случае, если сегодня - это уже завтра. В конечном счете, получается абсолютно тот же результат. Просто не забывайте о том, что часто одно и то же действие можно реализовать разными способами. Обратите также внимание на то, что я сразу же обновил и дату последнего просмотра.

Ну вот, мы разобрали все сложные моменты нашего счетчика, и осталось только соединить все вместе, чтобы получить код счетчика, учитывающего и просмотры странички за сегодня.


Часть 1Часть 2 - ее Вы читаете сейчасЧасть 3Часть 4


Свои мнения, пожелания и вопросы по выпускам Вы можете присылать по адресу mike@cherry-design.ru.
Я оставляю за собой право цитировать письма, пришедшие по вышеуказанному адресу.
Copyright © 2001-2008 Михаил Мельников. Перепечатка без разрешения запрещена.