Когда fopen терпит неудачу?

В моем PHP-коде я открываю файл и добавляю к нему текст. Я использую этот код:

$ourFileHandle = fopen($ourFileName, 'a') or die("can't open file"); 

Это происходит, когда загружается страница PHP. Теперь, что происходит, если два человека загружают страницу PHP одновременно? Будет ли этот код работать для одного из лиц, а для другого человека он выполнит die() ? В общем, когда может fopen провалиться?

Благодарю.

Solutions Collecting From Web of "Когда fopen терпит неудачу?"

TL; DR – просто используйте базу данных

Это не простой вопрос. То, что вы делаете, определенно не будет работать по желанию для нескольких параллельных запросов, так как большинство систем позволят всем запросам открыть файл, и, возможно, несколько сценариев смогут записывать в файл одновременно, вы можете оказаться в конечном итоге с мусором в файле, если вы это сделаете.

Возможная работа вокруг этого много и разнообразна, но я расскажу о трех здесь, которые я считаю наиболее жизнеспособными.

  1. Используйте базу данных. Это почти наверняка лучшее решение того, что вы пытаетесь сделать. RDBMS будет обрабатывать все эти проблемы параллелизма, не пропуская бит, у вас никогда не будет проблем с параллелизмом, если вы это сделаете.

  2. Запросите исключительную блокировку файла, используя flock() . Эта функция использует консультативную блокировку для предотвращения одновременного доступа нескольких одновременных процессов к файлу. Это будет соответствовать потребностям нескольких процессов PHP, но может не работать с другими внешними программами, если они не поддерживают ту же систему контроля за тем, что использует PHP.
    flock() "блокирует", пока в файл не будет зафиксирована блокировка. Это означает, что это повредит параллелизм запросов – только один запрос сможет записать файл одновременно. Более того, он не гарантирует, что блокировки будут обслуживаться в том порядке, в котором они были запрошены, поэтому вы можете оказаться в ситуации, когда один запрос никогда не получает блокировку файла, а остальные запросы, которые были получены позже, удовлетворяются.

  3. Используйте фоновый процесс для обработки доступа к файлу, и ваши сценарии взаимодействуют с процессом. Это похоже на прокрутку вашей собственной версии 1), и это не для слабонервных, но она может быть использована для большого эффекта при правильном выполнении.
    Используя эту модель, используется некоторая форма межпроцессного обмена для передачи данных, которые необходимо записать в файл, в фоновый (постоянный) процесс. Затем этот фоновый процесс управляет записью в файл, гарантируя, что сообщения написаны полностью и в правильном порядке. Обычно (при использовании PHP) такой IPC будет реализован с помощью сокетов. Это нетривиальное, но потенциально самое мощное решение.


С более общей точки зрения fopen() обычно терпит неудачу из-за проблемы с разрешениями или проблемы с операционной системой низкого уровня. Также ОС может предоставить «истинный» механизм блокировки, который предотвратит открытие другими программами других программ. Однако истинный «список причин fopen() может быть неудачным», трудно обеспечить, потому что существует так много возможностей.

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

fopen причине fopen выйдет из строя главным образом:

  • файл не существует
  • разрешения на файлы не позволяют открыть этот файл (написание, чтение, экскрементирование и т. д.).
  • файл используется другим процессом (т. е. сторонним приложением)
  • файл блокируется другим скриптом / активом PHP

fopen может выйти из строя, если у вас нет разрешений или есть другие проблемы низкого уровня os, fopen несколько раз не проблема, но одновременная запись в него может вызвать «чередование», поэтому используйте (блокирующую) flock .