2016-12-16 11 views
0

У меня есть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

Если у вас есть несколько процессов (PHP Apps), которые пишут в файл, используя те же 'file_get_contents', вы можете передать параметр:' LOCK_EX', который должен получить исключительная блокировка файла при переходе к записи. Другими словами, звонок fock() происходит между вызовом fopen() и вызовом fwrite(). Это не идентично вызову fopen() с режимом «x». –

+0

Вы уже это делаете. Если он не может записать файл (другой процесс использует его), он терпит неудачу. Coz. ​​Эта функция возвращает количество байтов, которые были записаны в файл, или FALSE при сбое. –

ответ

0

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


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

Я написал простые два сценариев тесты:

первого скрипт записывает файл 100MB (на медленном 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 является строкой 100MB, во втором сценарии $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 мс после первого, но до того, как второй сценарий было сделано писать. Таким образом, второй скрипт фактически получил доступ к заблокированному файлу.

  • второй сценарий termiated писать 229 мс после первого

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

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

10MB + были написаны 10 байт

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

Второй sc ript на самом деле добавила строку в конце файла

0

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

Benchmark ниже:

file_put_contents() для 1000000 записей - в среднем 3 тестов:

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

Еореп() FWRITE () для 1000000. пишет, fclose() - в среднем 3 тестов:

реальных 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