Есть веб приложение на PHP + БД на MySQL. После выполнения какого-либо SQL запроса путем отправки данных через HTML форму, если обновить страницу, то SQL запрос выполняется снова, т.к. повторно отправляются данные в POST запросе. Это приводит к дублированию записей в БД.
Как можно этого избежать? Делать редирект через header() для каждой операции в браузере или есть другие решения?
Делайте редирект.
Веб-приложение, это приложение, которое работает через HTTP-протокол. Это значит, что с приложением пользователь взаимодействует с помощью HTTP-запросов. Каждый раз когда ваш пользователь хочет чего-то от вашего приложения, он отправляет запрос.
Например, пользователь заполняет форму и отправляет в приложение данные для сохранения -- делает POST запрос на написанный вами обработчик. А что делает ваш обработчик? Он сохраняет данные в бд и внезапно передаёт пользователю HTML-документ! Получается он делает сразу два дела: сохраняет и выдаёт документ. Это довольно паршивый дизайн, пердставьте функцию в php, которая обновляет ваше имя в базе и заодно выводит список любимых фильмов -- довольно неудобно.
Чтобы всем было удобно, ваш обработчик должен на запрос сохранения данных сказать "я всё сохранил, можете полюбоваться результатами там-то". Это редирект. Такой ответ не содержит html-документ для пользователя, а только указывает где его посмотреть. Браузер пользователя сделает новый запрос автоматически и не даст пользователю повторять запрос на сохранение нажатием на обновление.
Потом можете добавить отправку форм javascript'ом. Схема не поменяется. Один обработчик -- один результат.
Лучший вариант будет использовать csrf token и редирект после обработки формы.
Если в кратце про csrf, то это работает так: При запросе страницы где расположена ваша форма, вы генерируете рандомную большую строку и куда-нибудь её записываете. Например в кэш. В форме добавляете hidden поле с именем _csrf (на самом деле может быть любое) и значением - ваша строка.
При получении данных из формы вы проверяете, что для этого пользователя вы генерировали строку и что пришедшая строка совпадает. И только тогда выполняете запись в базу. Кэш, конечно, подчищаете. Теперь если придет ещё один такой же запрос, он просто не пройдет. Дополнительно вы получите защиту от csrf атак.
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости