Подтвердить что ты не робот

Синхронные записи файлов PHP

У меня есть два разных файла PHP, которые записываются в один и тот же файл. Каждый PHP script вызывается действием пользователя двух разных HTML-страниц. Я знаю, что можно будет вызывать два файла PHP, но оба файла PHP попытаются записать в файл одновременно? Если да, что произойдет? Кроме того, можно сделать один из PHP неудачным изящно (запись файла просто завершится неудачно, а другой PHP может записать в файл), поскольку одна функция PHP менее важна, чем другая.

4b9b3361

Ответ 1

Обычный способ обращения к этому состоит в том, чтобы использовать оба сценария flock() для блокировки:

$f = fopen('some_file', 'a');
flock($f, LOCK_EX);
fwrite($f, "some_line\n");
flock($f, LOCK_UN);
fclose($f);

Это заставит сценарии ждать друг друга, чтобы выполнить работу с файлом, прежде чем писать на него. Если вам нравится, "менее важный" script может делать:

$f = fopen('some_file', 'a');
if(flock($f, LOCK_EX | LOCK_NB)) {
    fwrite($f, "some_line\n");
    flock($f, LOCK_UN);
}
fclose($f);

чтобы он ничего не делал, если обнаружил, что что-то занято файлом.

Ответ 2

Обратите внимание:

Начиная с PHP 5.3.2, автоматическая разблокировка при закрытии дескриптора файлового ресурса была удалена. Разблокирование теперь всегда должно выполняться вручную.

Обновленный обратный код:

if (($fp = fopen('locked_file', 'ab')) !== FALSE) {
    if (flock($fp, LOCK_EX) === TRUE) {
        fwrite($fp, "Write something here\n");
        flock($fp, LOCK_UN);
    }

    fclose($fp);
}

то есть. вам нужно вызвать flock (.., LOCK_UN) явно, потому что fclose() больше не делает этого.

Ответ 3

Обратите внимание, что posix указывает на атомарный доступ, если файлы открыты как append. Это означает, что вы можете просто добавить к файлу несколько потоков, и они не будут повреждены.

Я проверил это с дюжиной потоков и несколькими сотнями тысяч строк. Ни одна из строк не была повреждена.

Это может не работать со строками более 1 кБ, поскольку буферизация может превышать.

Это также может не работать в Windows, который не совместим с posix.

Ответ 4

Посмотрите на функцию flock.

Ответ 5

FYI: flock работает только в * nix и недоступен в Windows