Запись в файл изображения: безопасный способ заблокировать файл

#php #file-writing

#php #запись в файл

Вопрос:

У меня есть веб-сайт, где люди отправляют контент, который затем вставляется в собирательный образ. Мой код работает, но пока я обнаружил одну проблему:

Если 2 человека пытаются писать одновременно (скажем, оба отправлены в одно и то же время), это приводит к тому, что выходной файл становится размером 0 КБ, другими словами, это просто пустой файл.

Я пишу, используя выходной буфер, GD2 и file_put_contents вот так:

 ob_start();
imagejpeg($map);
file_put_contents(MAP, ob_get_contents(), FILE_BINARY);
ob_end_clean();
  

Мне интересно, каков наилучший способ решения этой проблемы?

Спасибо!

Ответ №1:

file_put_contents(MAP, ob_get_contents(), LOCK_EX)

Комментарии:

1. Я рассматривал это. Но не сделает ли это файл недоступным для записи одним из двух пользователей и не вернет ли уродливую ошибку о том, что файл недоступен для записи?

2. Второй скрипт, пытающийся получить блокировку, должен подождать, пока блокировка не будет снята.

3. @MT бы, но даже если их действия будут регулироваться каким-нибудь умным мьютексом (у меня есть один :)), второй пользователь переопределит все данные первого пользователя.

Ответ №2:

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

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

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