Ваш первый Сайт С использованием РНР-скриптов
ФУНКЦИЯ БЛОКИРОВКИ ПРИ ЗАПИСИ В ФАЙЛ
В гл. 4 я объяснил, почему надо использовать блокировку текстового файла при записи туда что-либо пользователями. При одновременном использовании программы для записи в файл несколькими посетителями могут возникнуть конфликтные ситуации, которые приведут к нарушению или полному разрушению информации в файле для записи. Поэтому при записи одним посетителем что-либо в файл данный файл временно блокируется для другого посетителя. При составлении кода для счетчика для блокировки мы использовали функции flock($descr, LOCK_EX) и flock($descr, LOCK UN), где Sdescr - дескриптор (идентификатор) файла. Мы ставили первую функцию до записи в файл, а вторую после записи в файл (см. листинг для счетчика в гл. 4). Для счетчика такая блокировка вполне приемлема, а вот для гостевой книги - нет. Если, например, второй посетитель отправляет свои данные и свою запись в гостевую книгу на сервер для записи в текстовый файл, но этот файл был временно заблокирован первым посетителем, который отправил свои данные на мгновение раньше, то данные второго посетителя пропадут и ему придется заполнять текстовые поля заново. Разумно было бы задержать отправку данных второго посетителя, пока текстовый файл, куда пока записываются данные от первого посетителя, не разблокируется. Составим такую программу, вернее, функцию, которая бы выполняла такую задачу. Создайте в редакторе новый файл и сохраните его в папке gostevaja под названием blok.php. Наберите код листинга 7.2.
Листинг 7.2 (файл Blok.Php) <?Php
Function bIokir($myfile, $zap)
{
If($fl=fopen($myfile, "a")) {
For($j=0; $j<10; ++$j) {
If(flock($fl, LOCK_EX)) break;
Else sleep(l);
}
Fwrite($fl, $zap); flush($fl);
Flock($fl, LOCK UN); fclose($fl);
Return true;
}
Else {
Return false;
}
} ?>
Код несложный, но мы его разберем:
Function blokir($myfile, $zap) - задаем функцию с именем blokir и двумя произвольными переменными. Они пока еще не определены, но при вызове данной функции переменной $myfile мы присвоим имя файла, а переменной $zap - данные, которые нужно записать в файл;
1{ - начало функции;
If($fl=fopen($myfile, "а")) - проверяется условие, можем ли мы открыть файл и присвоить ему идентификатор $fl, т. е. доступен ли этот файл. Если текстовый файл, куда будут записываться данные, доступен, то попытаемся осуществить его блокировку. Если файл уже был заблокирован, то мы опять заблокировать тот же файл пока не сможем. Будем ждать, пока файл не освободится; 2/
For($j=0; $j<10; $++j) - делаем, так называемый цикл ожидания. Цикл будет повторяться не более десяти раз. Ждем, когда мы сможем заблокировать файл. Функция sleep(l), которая на две строки ниже, каждый раз задерживает выполнение цикла на 1 секунду (именно такая цифра указана в аргументе). Таким образом, ожидание может длиться до 10 секунд;
3{ - начало цикла ожидания;
If(flock($fl, LOCK EX)) break; - если в течение 10 секунд нам все-таки удалось заблокировать файл, то выходим из данного цикла ожидания, при помощи инструкции break;
Else sleep(l); - если же заблокировать файл не удалось, ждем еще 1 секунду; 3} - конец цикла ожидания;
Fwrite($fl, $zap); - теперь, когда файл заблокирован, записываем туда то, что задано нам в аргументе $zap. Этот аргумент задается при вызове функции Blokir в переменную $zip;
Flush($fl); - данная функция очищает буфер записи;
Flock($fl, LOCK UN); - снимаем блокировку с текстового файла с идентификатором $fl
Fclose($fl); - закрываем файл;
Return true; - функция blokir возвратит true при удачном выполнении. Это иногда нужно для того, чтобы узнать в программе, куда будет вставлена данная функция, удачно ли эта функция выполнилась; 2}
Else - если же файл так и остался недоступным в течение 10 секунд, например, произошла какая-нибудь ошибка на сервере, то функция blokir не выполнится;
4{
Return false; - если текстовый файл останется недоступным в течение 10 секунд, функция blokir возвратит false;
4}
1} - конец функции.
Сохраните этот код, мы его будем использовать для создания гостевой книги.