Как отправить форму на ту же страницу
Не указывайте у формы атрибут action — тогда браузер отправит её на тот же адрес. Обработку поставьте в начало файла и запускайте, только если пришёл запрос POST:
<?php
$name = '';
$message = '';
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$message = trim($_POST['message'] ?? '');
if ($name === '' || $message === '') {
$error = 'Заполните оба поля';
} else {
// Здесь сообщение сохраняют в базу или отправляют письмом.
header('Location: contact.php?sent=1');
exit;
}
}
$sent = isset($_GET['sent']);
?>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Контакты</title>
</head>
<body>
<?php if ($sent): ?>
<p>Сообщение отправлено, спасибо!</p>
<?php endif; ?>
<?php if ($error !== ''): ?>
<p style="color: red"><?= htmlspecialchars($error) ?></p>
<?php endif; ?>
<form method="post">
<p><input name="name" value="<?= htmlspecialchars($name) ?>" placeholder="Имя"></p>
<p><textarea name="message" placeholder="Сообщение"><?= htmlspecialchars($message) ?></textarea></p>
<button>Отправить</button>
</form>
</body>
</html>Файл называется contact.php. Как он работает:
- Первое открытие — запрос GET: блок обработки пропускается, показывается пустая форма.
- Отправка — запрос POST в тот же файл. Если поле пустое, форма показывается снова с ошибкой и с уже введённым текстом — посетителю не нужно набирать всё заново.
- Если всё верно — данные обрабатываются, и браузер перенаправляется на
contact.php?sent=1, где видно сообщение «спасибо».
Зачем перенаправление после отправки
Без него страница с результатом — ответ на POST. Если посетитель нажмёт F5, браузер предложит отправить форму ещё раз, и сообщение придёт дважды (а заказ оформится дважды). После перенаправления на странице результата уже обычный GET, и обновление ничего не повторяет. Этот приём называют Post/Redirect/Get.
header() должен выполниться до любого вывода — поэтому обработка стоит выше HTML. Если появилась ошибка headers already sent, разбор — в справке Cannot modify header information.
Про action и PHP_SELF
В старых учебниках пишут action="<?php echo $_SERVER['PHP_SELF']; ?>". Так делать не надо: в PHP_SELF может попасть часть адреса, которую набрал посетитель, и без экранирования это уязвимость XSS. Если action всё же нужен, укажите имя файла явно (action="contact.php") или выведите адрес через htmlspecialchars. Проще всего — не писать action вовсе.
Несколько форм на одной странице
Если в файле две формы (например, поиск и подписка), отличайте их по имени кнопки:
<?php
if (isset($_POST['subscribe'])) {
// обработка подписки
}У кнопки этой формы должно быть name="subscribe": <button name="subscribe">Подписаться</button>. Нажатая кнопка отправляется вместе с полями формы, и по её имени понятно, какая форма пришла.
Подробнее о $_POST, проверке полей и htmlspecialchars — урок Формы.