2013-03-08 7 views
3

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

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

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

Спасибо.

+0

Это не сработает должным образом, если вы не заблокируете файл, что может повредить параллелизм. Что бы вы ни делали, почти наверняка было бы лучше сделать с базой данных. – DaveRandom

ответ

6

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

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

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

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

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

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


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

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

2

fopen потерпит неудачу в основном из-за этих причин:

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

1) Не имеет значения, 'a' режим создаст файл 2) достаточно справедливо 3) и 4) - это то же самое и не имеет значения, потому что он не пытался получить блокировку файла. – DaveRandom

+2

@DaveRandom, пожалуйста, «плюс мой ответ», потому что он спросил: «В общем, когда может fopen терпеть неудачу?» :) таковы причины и следствия, с помощью которых «fopen» может потерпеть неудачу в его выполнении. :) cheers – 2013-03-08 23:40:20

+0

@ZlatanO. +1;) Я ошибся – hek2mgl

1

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

Смежные вопросы