PHP: Безопасная работа с файлами. Пример счетчика
PHP без работы с файлами неинтересен. Динамика на сайтах обеспечивается различными счетчиками, голосованиями, рейтингами, опросами, комментариями посетителей. Разумеется, для всего этого можно использовать базы данных, например, MySQL, но не везде они есть.
Рассмотрим пример простейшего счетчика:
$cf1 = @file ("counter.txt"); $co = trim($cf1[0])+1; $cf2 = @fopen ("counter.txt", "w"); fput($cf2, $co); fclose ($cf2);
Все вроде замечательно, но только при условии, что на страницу, снабженную этим счетчиком, заходит не более одного посетителя в год. Чаще бывает наоборот. Одновременно несколько (десятков) человек просматривают данную страницу. Вероятность, что вышеприведенный код выполнится одновременно несколькими посетителями, велика.
Например, первый скрипт прочитал значение счетчика, увеличил на единицу и открыл файл для перезаписи. В этот момент второй скрипт прочитал значение счетчика из пустого файла (параметр "w" указывает на то, что открываемый файл становится пустым). Ошибочное чтение обнулило значение счетчика во втором скрипте. Первый скрипт записал в открытый файл правильное значение счетчика и закрыл файл. Второй скрипт увеличил значение счетчика на единицу: 0 + 1 = 1 и записал в файл это число. Таким образом, мы потеряли правильное значение счетчика.
Эту проблему можно решить, используя функцию flock(), но она не будет работать под IIS от Microsoft.
Воспользуемся другим способом: будем создавать файлы-флаги. Алгоритм простой: создаем файл-ловушку, работаем с нужным файлом, удаляем файл-ловушку.
cre_t("_counter"); . . . работаем со счетчиком del_t("_counter");
Рассмотрим подробнее функции cre_t() и del_t().
# Создаем замок на определенный файл function cre_t($fn){ $trp_p = 5; $present = 1; while ($present == 1){ $i = 0; $j = rand (2000, 5500); while ($i<$j){ $i = $i + 1; } if (!file_exists($fn)){ $mf = @fopen($fn, "w"); @fclose($mf); @fflush($mf); @chmod($fn, 0666); # Меняем атрибуты $present = 0; } else{ if ((time() - @filemtime($fname))>$trp_p){ @unlink ($fname); } } @clearstatcache($fname); } return 1; } # Снимаем замок с файла function del_t($fn){ return @unlink ($fn); }
Цикл в функции cre_t() работает до тех пор, пока существует файл-ловушка. Чтобы не происходило бесконечного зацикливания, добавлена проверка времени создания файла-ловушки. Если файл-ловушка существует более 5 секунд, то удаляем его самостоятельно. Установка атрибута 0666 на файл-ловушку позволяет различным скриптам удалять этот файл.
Описанный метод обеспечивает приемлемую защиту для безопасной работы с файлами. Но, разумеется, 100% безопасность возможна лишь с использованием базы данных и встроенной команды LOCK_TABLE.
PHP — это язык программирования, основанный на использовании скриптов. Данный язык широко применяется для создания различных front-end и back-end веб-приложений. Поддерживается по-умолчанию большинством хостеров, являясь одним из лидеров среди языков программирования, предназначенных для создания динамических интерактивных сайтов.
Интересные материалы на сайте:
Рассматривается способ подключения ODBC драйверов в 64-битной версии Windows 7.
Исправляем проблему дублей страниц на сайте и склейку доменов с www.
Аналитическая статья для любителей ставок в букмеккерских конторах.
Вводная статья о кодировании цифр с помощью таблиц азбуки Морзе.