#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, которые я пробовал некоторое время назад, похоже, не смогли надежно предотвратить столкновения в моей системе. Даже для простого счетчика веб-сайта я в конечном итоге использовал пустой файл со значением счетчика в фактическом имени файла после нескольких других попыток, потому что переименование файла, по крайней мере, является атомарной операцией.
Проблемы, вероятно, зависят от операционной и файловой систем и могут быть даже исправлены в наши дни, но если у вас продолжают возникать подобные проблемы, вы могли бы попробовать реализовать свой собственный способ блокировки, переименовав файл во что-то другое перед его изменением, а затем переименовав его обратно после того, как вы закончите.
В качестве альтернативы вы могли бы рассмотреть возможность сохранения изображения в базе данных.