fwrite — блокировка файлов Php при записи

Я тестирую свой код, используя небольшую базу данных в текстовых файлах. Самая важная проблема, которую я обнаружил: когда пользователи одновременно пишут в один файл. Для решения этой проблемы я использую flock,
ОС моего компьютера — Windows с установленным xampp (прокомментируйте это, потому что я понимаю, что стаи отлично работают над Linux без окон) Однако мне нужно сделать этот тест на сервере Linux.

На самом деле я проверил свой код, загрузив один и тот же скрипт в 20 окон одновременно. Первые результаты работают нормально, но после теста файл базы данных кажется пустым.

Мой код:

$file_db=file("test.db");
$fd=fopen("".$db_name."","w");

if (flock($fd, LOCK_EX))
{
ftruncate($fd,0);
for ($i=0;$i<sizeof($file_db);$i++)
{
fputs($fd,"$file_db[$i]"."\n");
}
fflush($fd);
flock($fd, LOCK_UN);
fclose($fd);
}
else
{
print "Db Busy";
}

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

-1

Решение

Я переписал сценарий, используя ответ @ lolka_bolka, и он работает. Итак, в ответ на ваш вопрос, файл $db_name может быть пустым, если файл test.db пустой.

0

Другие решения

ftruncate после fopen с «ш» бесполезно.

file функция

Возвращает файл в массиве. Каждый элемент массива соответствует строке в файле с новой строкой, все еще прикрепленной. В случае неудачи file () возвращает FALSE.

Вам не нужно добавлять дополнительный символ конца строки.

flock функция

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

Это означает, что file функция не зависит от блокировки. Это означает, что $file_db=file("test.db"); мог читать файл, в то время как другой процесс где-то между ftruncate($fd,0); а также fflush($fd);, Итак, вам нужно прочитать содержимое файла внутри блокировки.

$db_name = "file.db";
$fd = fopen($db_name, "r+"); // w changed to r+ for getting file resource but not truncate it

if (flock($fd, LOCK_EX))
{
$file_db = file($db_name); // read file contents while lock obtained
ftruncate($fd, 0);
for ($i = 0; $i < sizeof($file_db); $i++)
{
fputs($fd, "$file_db[$i]");
}
fflush($fd);
flock($fd, LOCK_UN);
}
else
{
print "Db Busy";
}
fclose($fd); // fclose should be called anyway

Постскриптум вы можете протестировать этот скрипт с помощью консоли

$  for i in {1..20}; do php 'file.php' >> file.log 2>&1 & done
0

По вопросам рекламы [email protected]