WebScript.Ru
C:\   главная  ::   о сайте  ::  каталог скриптов  ::  гнездо  ::  форум  ::   авторам  :: Новостройки ::   ХОСТИНГ  ::

|| разделы::
|| поиск по сайту::

|| реклама::
|| новости почтой::
Рассылки Subscribe.Ru ::



Новости сайта WebScript.Ru
Популярные статьи

Hot 5 Stories

|| рекомендуем::




Пишем простейший текстовой счётчик


Прислал: Евгений Емельянов [ 26.08.2003 @ 16:27 ]
Раздел:: [ Статьи по PHP ]


Итак, писать мы будет простейший текстовой счётчик. Для начала решим для себя, как именно он будет работать. Всего наш скрипт будет состоять из четырёх файлов :
-Файл
для хранения ip пользователей (ip.txt)
-Файл
для хранения данных счётчика (counter.txt)
-Сам
файл скрипта (counter.php)
-Шаблон
вывода счётчика (template.html)

Алгоритм работы очень прост:
-Когда
скрипт запускается, он получает ip запустившего его браузера.
-По
ip проверяем, были ли уже запросы от этого браузера или нет.
-Если
не были — добавляем ip в базу и прибавляем по единичке ко всем счётчикам.
-Если
уже были — прибавляем по одному поинту к хитам.
-Выводим
данные счётчика.

Отображать наш счётчик будет:
-Просмотров
всего
-Просмотров
сегодня
-Уникальных
посетителей сегодня

Как видите, в теории всё очень просто. На практике не намного сложнее. Создаём все четыре файла. Текстовые файлы не трогаем — в них будет хозяйничать наш скрипт. Шаблон вывода оставим на потом. Открываем counter.php и приступаем.


# Начало файла counter.php
counter.php

<?php
$ip=getenv("REMOTE_ADDR");
#Получаем ip запустившего скрипт компьютера
$date=date('d.m.Y',time());
#Присваиваем переменной $date текущую дату

#Следующий блок считывает файл с ip адресами
$fo = fopen ("ip.txt", 'r');
#Открываем файл
flock($fo,1);
#"Запираем" файл для чтения. Если кто-то ещё захочет прочитать этот файл - его запрос "встанет в очередь"
$data = fread ($fo, filesize("ip.txt"));
#Считываем информацию из файла и присваиваем её переменной $data
flock($fo,3);
# Разблокируем файл
fclose ($fo);
#Закрываем файл

#Нижеследующий блок повторяет ту же самую процедуру с файлом counter.txt
$f = fopen ("counter.txt", 'r''r');
flock($f,1);
$counts = fread ($f, filesize("counter.txt"));
flock($f,3);
fclose ($f);

list($d,$total,$hits,$hosts)=explode("|",$counts);
# Проходимся по данным счётчика и присваиваем их соответствующим переменным. Алгоритм работы простой - идём до разделителя( "|" ), присваиваем значение первой переменной из list, идём до следующего разделителя и так далее.


#Проверяем, соответствует ли дата в файле счётчика текущей дате. Если нет - обнуляем файл с ip файлами и некоторые значения счётчика.
if ($d!=$date)
{
$d=$date;
#Обновляем дату
$hits=0;
#Просмотров сегодня теперь равны нулю
$hosts=0;
#То же самое с уникальными посетителями
$erase=fopen("ip.txt",'w+');
#Открываем файл с ключём "w+" - это значит, что данные файла обнуляются и на их место мы записываем новые данные
flock($erase,2);
#Запираем файл для записи
fputs($erase,"");
#Записываем в файл "всемирное ничто"
flock($erase,3);
fclose($erase);
}


#Теперь проверяем, есть ли ip у нас в базе.
if (!stristr($data,$ip))
# Если нет
{
$file=fopen("ip.txt",'a');
flock($file,2);
fputs($file,$ip."rn");
#Записываем новый ip в базу
flock($file,3);
fclose($file);
$total++;
$hits++;
$hosts++;
#Прибавляем к значениям счётчика по единице
}
else
#Если ip уже есть в базе, прибавляем по единице только хитам
{
$total++;
$hits++;
}

#Записываем новые данные счётчика в файл
$wfile=fopen("counter.txt",'w+');
flock($wfile,2);
fputs($wfile,$d."|".$total."|".$hits."|".$hosts);
#Записываем данные с разделителем ("|"), для удобной сортировки, которую мы проводили выше
flock($wfile,3);
fclosвыше
flock($wfile,3);
fclose($wfile);

#Всё, теперь можно выдавать пользователю показатели счётчика
include ("template.html");
?>


Шаблон вывода данных счётчика делается очень просто. Файл template.html выглядит так:


<?php echo <<<HTML

[ <b>$total</b> :: $hits :: $hosts ]
#Это и есть сам шаблон вывода.

HTML;
?>


#Конец файла counter.php

Вот и всё, мы написали простой счётчик.
Можно сделать небольшое усовершенствование скрипта. К примеру, если вы не хотите, что бы кто-нибудь мог посмотреть ip адреса людей, посетивших сегодня вашу страницу. Для этого надо поместить текстовые файлы в отдельныю папку, в этой же папке создать файл .htaccess и написать в нём всего одну строчку:
deny from all

Не забудьте поставить разрешение на запись в текстовые файлы и в папку, а так же поменяйте путь к этим файлам в скрипте.
Что бы вывести счётчик на страницу, в нужном месте пометите следующий код :
<?php include(«путь_к_папке_скрипта/counter.php») ?>

На этом разрешите откланяться. Желаю удачи и успехов в постижении нелёгкого дела программиста.

codex
xcodex.com




 :::::  RomikChef пишет 26.08.2003 @ 16:45 
зачем файл лочить на чтение?
 :::::  Евгений Емельянов пишет 26.08.2003 @ 20:08 
В некоторых случаях одновременный процесс чтения и записи может привести к ошибкам. Лок на чтение можно и опустить, но с ним будет надёжнее.
 :::::  ЧеКот пишет 27.08.2003 @ 12:37 
Я бы не претендовал на "учебность" этого скрипта: работа с блокировками имеет типичную ошибку.
#Записываем новые данные счётчика в файл
$wfile=fopen("counter.txt",'w+');
flock($wfile,2);
Между вызовами fopen и flock файл уже обнулен, но еще не заблокирован. В этот момент он может быть считан параллельным процессом, и в итоге счетчики будут обнулены. Кроме того, еще более вероятным при параллельной работе двух экземпляров скрипта является то, что оба считают одни и те же данные, а потом второй запишет свою версию измененных данных, так что изменения, внесенные первым, будут потеряны. Соответственно, эксклюзивную блокировку надо ставить сразу и закрывать файл нельзя (это и не нужно).

Правильная последовательность действий примерно такая (прошу прощения, если где опечатался, пишу навскидку по памяти):
$fp=fopen($filename,'a+');
flock($fp,LOCK_EX);
rewind($fp);
$data=fread($fp,filesize($filename));
// делается какая-то модификация данных...
ftruncate($fp);
rewind($fp);
fwrite($fp,$data);
// flock($fp,LOCK_UN); // необязательный вызов
fclose($fp);
 :::::  Евгений Емельянов пишет 27.08.2003 @ 13:05 
Согласен с вами, ЧеКот. Ваше замечание верно. А насчёт учебности. Я описал принип работы, а вы уже дополнили некоторые тонкости, в любом скрипте есть спортные места, не так ли?
 :::::  tommy пишет 27.08.2003 @ 16:13 
я вот графический счетчик для wap написал (с поддержкой многих пользовалелей)
так вот : там меньше кода :) (да ... с уникальностью в wap только плохо - там десятки тысяч с одного IP :) )
 :::::  Alexey пишет 27.08.2003 @ 17:05 
Классная статья, спасибо огромное, Евгений! Главное - написано понятно.
 :::::  xml пишет 27.08.2003 @ 17:42 
если в программе комментарии - значит это плохая программа.
хорошая в комментариях не нуждается - просто надо пример кода было привести
(желательно если он будет при этом рабочий)
 :::::  ЧеКот пишет 28.08.2003 @ 10:29 
Согласен с Вами, Евгений. С точки зрения "показать, какие действия должен делать счётчик", статья свою функцию выполняет, однако лучше вообще не показывать работу с чем-то (блокировками), чем показывать её неверно, тем более в таком неочевидном вопросе. Либо явным образом указать на это. А то люди ведь примут за чистую монету, что так и надо. Учитывая, что многие программисты - самоучки, некоторые выяснят, что последовательность действий неверна, только когда сами на грабли наступят.

2 xml: Если программист придерживается такой точки зрения, значит это плохой программист ;) Или он никогда не разбирал чужие программы с алгоритмом чуть сложнее, чем 2+2.
 :::::  Neo пишет 31.08.2003 @ 01:06 
Вообще рекомендовал бы IP вырывать из HTTP_X_FORVARDED_FOR или как-то так эта переменная называеться.

Когда считываете из REMOTE_ADDR то пользователь, использующий Proxy за нового не сойдёт.

А так есть вероятность, что прокси анонимный - и это уже новый посетитель!
 :::::  Макс пишет 01.09.2003 @ 14:08 
 :::::  MrGreeN пишет 19.09.2003 @ 15:35 
2Neo
если уж на то пошло, то и HTTP_X_FORVARDED_FOR и REMOTE_ADDR обеспечить обязательное опознавание клиента не могут, так же в прочем как и куки...
 :::::  Alex пишет 06.10.2003 @ 06:28 
Etot script mozno ochen legko oboiti. Prosto ispol'zovat proxy
 :::::  Вася Пупкин пишет 08.10.2003 @ 19:56 
Привет. Евгений, написал бы ты этот скрипт с mysql, придирок с моей стороны было бы меньше,
этот счетчик лего ломануть, всмысле незнакомый человек может просто набрать www.site.com/admin_room/counter/ip.txt, и увидеть все ипы, что крайне нежелательно. Сейчас ты мне скажешь, я показал принцип работы, но новички ж это смотрят. Они берут то что ты написал.
Можно было бы сделать умнее, создать ip.php и в него вставить строку header("location:../../../index.php");
Вот и все, вся защита. Я уже не говорю о ненужности определения по ипу.
И обо всех остальных неточностях...

Ну в принципе мне понравилось, ты молодец!
 :::::  Вася Пупкин пишет 01.11.2003 @ 05:49 
для новичком есть приписка :)

"Вот и всё, мы написали простой счётчик.
Можно сделать небольшое усовершенствование скрипта. К примеру, если вы не хотите, что бы кто-нибудь мог посмотреть ip адреса людей, посетивших сегодня вашу страницу. Для этого надо поместить текстовые файлы в отдельныю папку, в этой же папке создать файл .htaccess и написать в нём всего одну строчку:
deny from all" (с) Евгений Емельянов

а так счетчик под пиво потянит ... чеснео говоря я его и взял для себя .. приписал правда еще кое что ну немного поправил по д себя и все .. лень писать с начала :)
 :::::  Вася Пупкин пишет 14.12.2003 @ 13:30 
.htaccess и написать в нём всего одну строчку:
deny from all

МЛЯ. Незаметил. Тада все в порядке, но на эт тоже не стоит полагатся. Ломануть можно и в обход.
Например присвоить одной из переменной в хедере свое значение и тада все пучком. Просматривай хыть все файлы.
 :::::  Vic пишет 15.05.2004 @ 18:49 
Многоувожаемый т-щ Вася Пупкин, пишет вам, якобы ламернутый пользователь: а что вы только что сказали?
-||- только начинающий хакер: это бесполезно...
-||- только хакер: других способов чтоль мало?

да и вообще... нормальные люди руками конфигят php.ini и иногда пользуют unset($qwerty); ...
да и как ты хотел, поменяв значение переменной в хеадере просматривать файлики?.... дописав туда чуток кода?... боюсь, от этого спасает наличие рук при конфиге php.ini
 :::::  PPS пишет 13.08.2004 @ 18:41 
".htaccess и написать в нём всего одну строчку:
deny from all

МЛЯ. Незаметил. Тада все в порядке, но на эт тоже не стоит полагатся. Ломануть можно и в обход.
Например присвоить одной из переменной в хедере свое значение и тада все пучком. Просматривай хыть все файлы.
"
В обход .htaccess эко загнул, тогда ради кучки IP хост ломать придется (:0)
 :::::  User пишет 10.10.2004 @ 10:58 
Я очень плохо разбираюсь в веб технологиях. Объясните пожалуйста, а не произойдёт ничего страшного, если Permissions для текстовых файлов и директории где они лежат установить 777. Файл .htacess со значением deny from all естественно лежит в директории с этими текстовыми файлами, но может ли кто-то не напрягаясь сломать такой сервер?
 :::::  Petro пишет 29.06.2010 @ 23:24 
я незнаю неработает и все голова трищит
 :::::  Александр пишет 08.01.2012 @ 00:19 
Простите, но это какая-то фигня получается
В строке
$f = fopen ("counter.txt", 'r''r');
обнаружилась синтаксическая ошибка. Когда я заменил одинарные кавычки на двойные, она всё равно осталась. Когда я убрал одну из букв "r", мне был задан вопрос, что это за странное слово такое: "fclosвыше"
Даже не знаю, на каком это искусственном языке.
Не говоря уж о том, что эта страница, когда подключил её инклюдом, мне поломала весь дизайн.
Я, конечно, понимаю, что здесь мне никто ничего не должен, но всё-таки постарайтесь хотя бы проверять, что сюда постите.
Имя:
Email:
URL

Введите сумму двух чисел девять и шесть (девять+шесть=?)
Запомнить мою информацию

* Html запрещен* Ваш E-mail опубликован не будет.

Copyright © 2000-2001 WebScript.Ru nas@webscript.ru
Design © 2001 by Parallax Design Studio (aka Spectator.ru)
Все торговые марки и авторские права на эту страницу принадлежат их соответствующим владельцам.
Сгенерировано за: 0.0344541