Глиф Учебники

Как отправить форму на ту же страницу

Справочник · PHP · 1 минута чтения

Не указывайте у формы атрибут action — тогда браузер отправит её на тот же адрес. Обработку поставьте в начало файла и запускайте, только если пришёл запрос POST:

PHP
<?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. Как он работает:

  1. Первое открытие — запрос GET: блок обработки пропускается, показывается пустая форма.
  2. Отправка — запрос POST в тот же файл. Если поле пустое, форма показывается снова с ошибкой и с уже введённым текстом — посетителю не нужно набирать всё заново.
  3. Если всё верно — данные обрабатываются, и браузер перенаправляется на 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
<?php
if (isset($_POST['subscribe'])) {
    // обработка подписки
}

У кнопки этой формы должно быть name="subscribe": <button name="subscribe">Подписаться</button>. Нажатая кнопка отправляется вместе с полями формы, и по её имени понятно, какая форма пришла.

Подробнее о $_POST, проверке полей и htmlspecialchars — урок Формы.