Fopen (файл, w +) обрезает файл, прежде чем я могу проверить, заблокирован ли он с помощью flock()

У меня есть функция, которая получает имя файла и объект json для записи в текстовый файл.

Объект обновляется и должен полностью заменить текущее содержимое файла. У каждого посетителя сайта есть свой файл. Несколько быстрых изменений создают ситуацию, когда файл усекается на fopen(file,w+), а затем не записывается так, как он заблокирован. Конечный результат - пустой файл.

Я уверен, что есть стандартный простой способ сделать это, поскольку это такая обычная деятельность. Идеально, что я ищу, это способ проверить, заблокирован ли файл перед усечением файла с помощью fopen в w+ или способом переключения режимов.

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

Здесь функция, которую я имею до сих пор:

function updateFile($filename, $jsonFileData) {
    $fp = fopen($filename,"w+");
    if (flock($fp, LOCK_EX)) {  
        fwrite($fp, $jsonFileData);
        flock($fp, LOCK_UN);
        fclose($fp);
        return true;
    } else {
        fclose($fp);
        return false;
    }
}

Ответ 1

Пример # 1 из Руководство по PHP будет делать то, что вы хотите, с небольшими изменениями. Используйте "c" mode, чтобы открыть файл для записи, создать его, если он не существует, и не обрезать его.

$fp = fopen("/tmp/lock.txt", "c");

if (flock($fp, LOCK_EX)) {  // acquire an exclusive lock
    ftruncate($fp, 0);      // truncate file
    fwrite($fp, "Write something here\n");
    fflush($fp);            // flush output before releasing the lock
    flock($fp, LOCK_UN);    // release the lock
} else {
    echo "Couldn't get the lock!";
}

fclose($fp);

Полное описание режима "c":

Откройте файл для записи. Если файл не существует, он создается. Если он существует, он не усекается (в отличие от "w" ), и вызов этой функции не выполняется (как в случае с "x" ). Указатель файла расположен в начале файла. Это может быть полезно, если требуется получить консультативную блокировку (см. flock()), прежде чем пытаться изменить файл, так как использование w обрезать файл до того, как была получена блокировка (если требуется усечение, ftruncate() можно использовать после запроса блокировки).

Это не похоже, что вам это нужно, но также есть соответствующий режим "c+", если вы хотите читать и писать.