Что может произойти между file_exists и сохранением файла с определенным именем (php)?

Из -за того, как сервер может обрабатывать запросы (-> одновременные запросы к PHP Script), у меня возник вопрос о том, что может произойти, если скрипт проверяет имя файла, а затем сохраняет файл.

Например: пользователь A запрашивает "save.php". Очень короткое время спустя пользователь Б запрашивает "save.php". Сценарий пользователя A находится в точке, где сценарий проверяет, существует ли файл. Файл не существует, и ДО того, как файл будет записан, сценарий пользователя B находится в точке, где он проверяет наличие файла. Так что это также говорит о том, что файл не существует. Теперь скрипт пользователя А записывает файл. И сценарий пользователя B перезаписывает файл, если они имеют одинаковое имя файла. (Имя файла случайное, но это может произойти).

Как я могу избежать таких вещей? Есть ли что-то вроде Tablelocking и транзакций для PHP-команды? Возможно ли, что сценарий пользователя B превосходит сценарий пользователя A, потому что он получает больше ресурсов с сервера?

С наилучшими пожеланиями

2 ответа

Решение

Пожалуйста, посмотрите на:

http://www.php.net/manual/en/function.fopen.php

Вам нужно использовать эксклюзивную блокировку при создании файла следующим образом:

$handle = fopen("/home/somewhere/yourfile.txt", "x");

Когда вы делаете это таким образом, вторичные попытки доступа (пользователь B, C) к файлу вернут false и сгенерируют предупреждение, так как файл создан и заблокирован исключительно пользователем A.

Как только файл будет создан, file_exists будет иметь значение true, но другие пользователи не смогут открыть его, потому что он будет создан с исключительно заблокированным состоянием.

Когда пользователь A заканчивает свою работу, последующие вызовы могут получить доступ к файлу

Ручной ввод для режимов x и x+:

'Икс'

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

"Х +"

Создать и открыть для чтения и письма; в противном случае он ведет себя так же, как "х".

Используйте семафор, если ваша установка php поддерживает это: http://be2.php.net/manual/en/ref.sem.php

В качестве альтернативы вы также можете проверить функцию flock(): http://be2.php.net/manual/en/function.flock.php

Другие вопросы по тегам