
Статьи > PHP - грамотная работа с файлами Обычно работа с файлом (небезопасная модель без блокировки файла) представляет собой последовательность действий в виде: открытие файла (получение его дескриптора), работа с содержимым, закрытие файла. И в самом распространенном варианте выглядит так: <?php
$fp = fopen ( "path_to_file" , "a" ); //ОТКРЫТИЕ fputs ( $fp , "$data " ); //РАБОТА С ФАЙЛОМ fclose ( $fp ); //ЗАКРЫТИЕ ?> Здесь мы открыли файл в режиме добавления информации в конец файла, записали в него порцию информации $data и затем закрыли его (Предполагается, что у нас есть права на запись в файл). Это самое простое и самое первое, что нам могло прийти в голову и что мы реализовали. Если вы уверены, что никаких проблем с файлом не возникнет или что у вас не так много посетителей, чтобы что-то сломалось, то это ваше право - можете закрыть статью и жить спокойно! ;) Но нужно что-то делать. Одним из примеров трагедий может служить сайт http://manlix.ru, в котором постоянно "падает" форум и/или счетчик посетителей. Я, конечно, не берусь судить, что только некорректная работа с файлами тому виной, но, по-моему, это очевидно. Пока число посетителей было сравнительно небольшим, все корректно функционировало, как только иногда одновременно стало появляться до 10 пользователей одновременно, начались казусы с счетчиком и форумом. Как же это преодолеть? Оказывается просто, всего лишь добавив несколько строк в операцию работы с файлами: <?php
$fp = fopen ( "path_to_file" , "a" ); //открытие flock ( $fp , LOCK_EX ); //БЛОКИРОВКА ФАЙЛА fputs ( $fp , "$data " ); //работа с файлом fflush ( $fp ); //ОЧИЩЕНИЕ ФАЙЛОВОГО БУФЕРА И ЗАПИСЬ В ФАЙЛ flock ( $fp , LOCK_UN ); //СНЯТИЕ БЛОКИРОВКИ fclose ( $fp ); //закрытие ?> В данном примере мы открыли файл для добавления в него информации Предполагается, что у нас есть права на запись в файл). Затем применили исключительную блокировку и тем самым сделали наш скрипт единственным процессом, который в текущий момент имеет доступ к файлу. Блокировка действительна все время от выполнения функции flock ($fp,LOCK_EX) и до выполнения flock ($fp,LOCK_UN). Между этими функциями находятся операторы, выполнение которых будет "безопасным" для файла. Другие процессы смогут получить доступ к файлу не раньше снятия блокировки. Важным моментом является применение функции fflush ($fp). Транзакции изменения данных могут быть записаны с специальный файловый буфер и сброшены на диск позже, когда блокировка будет уже снята и снова будет опасность сбоя в работе. Поэтому данной функцией мы принудительно записываем изменения на диск, сбрасывая содержимое буфера. Еще одним не менее важным моментом является, само открытие файла! Мы не случайно используем режим "a" ("a+"). Если нам будет необходима запись в начало файла с удалением предыдущего содержимого, то следует воздержаться от применения режима "w" ("w+"), поскольку очищение файла предполагает удаление не только содержимого, но и самого файла с последующим созданием аналогичного. Так как этот процесс будет выполнен до исключительной блокировки, то также существует вероятность сбоя в работе. В данном случае стоит применять следующий прием : <?php
$fp = fopen ( "path_to_file" , "a" ); //открытие flock ( $fp , LOCK_EX ); //блокировка файла ftruncate ( $fp , 0 ); //УДАЛЯЕМ СОДЕРЖИМОЕ ФАЙЛА fputs ( $fp , "$data " ); //работа с файлом fflush ( $fp ); //очищение файлового буфера и записьв файл flock ( $fp , LOCK_UN ); //снятие блокировки fclose ( $fp ); //закрытие ?> Здесь мы открыли файл для записи в него, затем применили исключительную блокировку, и только уж потом применили функцию ftruncate ($fp,0) которая выполнила так необходимую нам очистку файла от содержимого. Вот вроде бы и все, что я хотел вам для начала рассказать! Успехов Вам в нашем нелегком труде! До новых встреч, до новых статей! Реклама |