PHP fopen (флаг x) гарантированно запускается только один раз?


PHP позволяет нам использовать флаг x при выполнении fopen:

Создайте и откройте только для записи; поместите указатель файла в начало файла.

Если файл уже существует, вызов fopen() завершится ошибкой, возвращая FALSE и генерируя ошибку уровня E_ ПРЕДУПРЕЖДЕНИЕ.

Если файл не существует, попытайтесь его создать. Это эквивалентно указанию флагов O_EXCL|O_CREAT для базовой открытой(2) системы вызов.

Означает ли это, что независимо от того, сколько одновременных запросов fopen у нас есть (от разных пользователей), гарантируется, что файл будет создан только один раз и никогда не будет перезаписан?

if ($handle = fopen("part006", "x+b")) {
    do_some_processing();
    echo "You managed to process.";
    /*

    can we guarantee that only 1 user (http request)
    will ever process the function and see the
    message "you managed to process" ?

    */
} else {
    echo "You failed to process.";
}
Author: Pacerier, 2013-03-09

1 answers

Ответ: Гарантируется, что файл будет создан только один раз и никогда не будет перезаписан, если другие процессы также используют O_EXCL. Если они этого не сделают, файл может быть перезаписан. Таким образом, открытие (создание) файла с помощью O_EXCL не означает, что файл в некоторой степени защищен от записи

Объяснение: fopen использует базовый системный вызов open. Со страницы справочника: man 2 open

O_EXCL

Если заданы O_CREAT и O_EXCL, функция open() завершится ошибкой, если файл существует. Проверка существования файла и создание файла, если он не существует, должны быть атомарными по отношению к другим потокам, выполняющим open(), называющим то же имя файла в том же каталоге с набором O_EXCL и O_CREAT. Если заданы O_EXCL и O_CREAT, а имена путей являются символической ссылкой, функция open() завершится ошибкой и установит значение errno в [EEXIST], независимо от содержимого символической ссылки. Если задано значение O_EXCL, а значение O_CREAT не задано, результат не определен.

 1
Author: hek2mgl, 2013-03-09 04:04:21