file_put_contents добавление данных в файл, записываемый другим процессом

я имею

$bytesCount = file_put_contents( "somefile.log", "some text\n", FILE_APPEND | LOCK_EX );

Что произойдет, если другой процесс пишет ** на somefile.log?

Есть ли file_put_contents терпит неудачу с ошибкой во время выполнения?

Если не с $bytesCount === false

Или он приостанавливает выполнение сценария до тех пор, пока файл не будет разблокирован, а затем выполняет операцию записи?


(**) или, в более общем случае, другой процесс имеет эксклюзивную блокировку файла


[ Я нахожусь на *nix платформа с php 5.6 ]

0

Решение

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


Доказательство:

Я написал простой тест с двумя сценариями:

первый сценарий записывает файл размером 100 МБ (на медленном диске с USB2-подключением);

второй скрипт добавляет короткую строку в тот же файл.

ядро из двух сценариев эти четыре строки:

echo Milliseconds() . ": Start writing file on file\n";
$bytesCount = file_put_contents( "/Volumes/myHD/somefile.txt", $buffer, FILE_APPEND | LOCK_EX );
var_export( $bytesCount );
echo "\n" . Milliseconds() . ": Done writing on file\n";

куда Milliseconds() это функция, которая возвращает текущую метку времени Unix в миллисекундах.

В первом скрипте $buffer строка 100 МБ, во втором скрипте $buffer = "MORE-DATA\n";

Запуск первого скрипта и быстрый запуск второго приведут к следующим выводам:

Сценарий 1:

$ php test1.php
1481892766645: Start writing file on file
100000000
1481892769680: Done writing on file
$

Сценарий 2:

$ php test2.php
1481892766831: Start writing file on locked file
10
1481892769909: Done writing file on locked file
$

Обратите внимание, что:

  • второй сценарий пытался написать 186 мс после первого, но до того, как второй сценарий был закончен. Таким образом, второй скрипт на самом деле получил доступ к заблокированному файлу.

  • второй сценарий условно записан через 229 мс после первого

Проверка результата после того, как оба сценария прекратили выполнение:

$ stat -f%z /Volumes/myHD/somefile.txt
100000010
$

10 МБ + 10 байт было написано

$ tail -c 20 /Volumes/myHD/somefile.txt
0123456789MORE-DATA
$

Второй скрипт фактически добавил строку в конец файла

1

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

Должно быть очевидно, что это следует использовать, только если вы делаете одну запись, если вы пишете несколько раз в один и тот же файл, вы должны обрабатывать его самостоятельно с помощью fopen и fwrite, fclose, когда вы закончите писать.

Тест ниже:

file_put_contents () для 1 000 000 записей — в среднем 3 теста:

реальный 0m3.932s
пользователь 0m2.487s
sys 0m1.437s

fopen () fwrite () для 1 000 000 операций записи, fclose () — среднее из трех тестов:

реальный 0m2.265s
пользователь 0m1.819s
sys 0m0.445s

Для перезаписи при использовании ftp это полезно:

/* create a stream context telling PHP to overwrite the file */
$options = array('ftp' => array('overwrite' => true));
$stream = stream_context_create($options);

http://php.net/manual/en/function.file-put-contents.php

0

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