Какой самый эффективный способ чтения, а затем перезаписать содержимое файла в php?

Я хочу прочитать файл в строку, изменить содержимое и записать обработанную строку в файл. Кроме того, другой запрос к серверу может начаться слишком рано и попытаться записать тот же файл до завершения первого - это НИКОГДА не должно происходить (пока я использую flock) - было бы еще лучше, если бы скрипт блокировался до тех пор, пока не замок снят.

Вот какой-то неполный подход

$h = fopen($fp, 'a+');
flock($h, LOCK_EX);
$oTxt = '';
while (!feof($file)) {
    $oTxt .= fread($h, 8192);
}
rewind($h);
ftruncate($h, 0)
fwrite($h, );    // process contents and write it back
flock($h, LOCK_UN);
fclose($h);

Примечание. Этот вопрос очень похож на Какой лучший способ прочитать, а затем перезаписать содержимое файла в php? (в моем случае это файл json, который я хочу декодировать, вставить или отредактировать какой-то узел, а затем снова закодировать его), но это не так. дубликат.


person IARI    schedule 20.07.2015    source источник
comment
Тот факт, что вы имеете дело с json, кажется недостаточным, чтобы отличить ваш вопрос от того, на который вы ссылаетесь. Каковы некоторые другие различия?   -  person gymbrall    schedule 20.07.2015
comment
Вопросы по сути одинаковые. Проблема с этим другим вопросом заключается в том, что ни один из ответов не является хорошим, потому что они на самом деле не решают проблему блокировки.   -  person Barmar    schedule 20.07.2015
comment
Обратите также внимание, что разница в том, что я хочу, чтобы решение было не самым чистым, а самым эффективным.   -  person IARI    schedule 20.07.2015


Ответы (1)


Вы можете заменить цикл while одним вызовом stream_get_contents. И вы должны использовать режим r+ для чтения и записи файла; a+ поместит поток в конец файла при запуске, поэтому читать будет нечего.

$h = fopen($fp, 'r+');
flock($h, LOCK_EX);
$oTxt = stream_get_contents($h);
// Process contents
rewind($h);
ftruncate($h, 0);
fwrite($h, $oTxt); 
flock($h, LOCK_UN);
fclose($h);
person Barmar    schedule 20.07.2015
comment
спасибо, я использовал не + (ошибка копирования), а w+, что тоже было неправильно ^^ Я попробую :) - person IARI; 20.07.2015
comment
но что, если flock вернет false? - person IARI; 20.07.2015
comment
Вы можете добавить проверку ошибок. Вы также должны проверить, возвращает ли fopen() false. Если у вас есть доступ для открытия файла в режиме записи, я не могу понять, почему flock не получится. - person Barmar; 20.07.2015
comment
Я уже проверяю все это в моем фактическом коде (просто оставил это здесь, чтобы улучшить читаемость). Но есть ли встроенный способ блокировки стада? или я должен написать это, включая тайм-аут? (вы просто должны любить php... -.-) - person IARI; 20.07.2015
comment
По умолчанию он блокируется, вы должны использовать LOCK_NB, чтобы сделать его неблокирующим. - person Barmar; 20.07.2015
comment
Это то же самое, что и в Си. - person Barmar; 20.07.2015