#6 php как узнать, что форму отправили: REQUEST_METHOD, htmlspecialchars и сохранение значений
Primary tabs
В уроке про POST мы различали «форму отправили» и «на страницу просто зашли» косвенно — по наличию элементов в $_POST. Разберём правильный приём: проверку метода запроса. Заодно научимся не терять введённые значения после отправки и познакомимся с первой функцией безопасности — htmlspecialchars().
Страница урока: http://localhost:19791/lessons/lesson06-form-sent/
Немного теории
PHP собирает служебные сведения о запросе в массив $_SERVER — про него читайте в учебнике: переменные сервера и заголовки HTTP-запроса. Нам нужен элемент $_SERVER['REQUEST_METHOD'] — он содержит метод запроса: 'GET', когда на страницу просто зашли, и 'POST', когда форму отправили. А про превращение спецсимволов HTML в безопасные последовательности читайте там же: кодирование тегов HTML.
Код страницы
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Сравнение чисел: аккуратная форма</title>
</head>
<body>
<h1>Сравнение чисел</h1>
<?php
$isPosted = $_SERVER['REQUEST_METHOD'] === 'POST';
$a = '';
$b = '';
if (isset($_POST['a'])) {
$a = $_POST['a'];
}
if (isset($_POST['b'])) {
$b = $_POST['b'];
}
$isValid = $isPosted && is_numeric($a) && is_numeric($b);
?>
<form action="" method="post">
<p>Число A:
<input type="text" name="a"
value="<?php echo htmlspecialchars($a); ?>">
</p>
<p>Число B:
<input type="text" name="b"
value="<?php echo htmlspecialchars($b); ?>">
</p>
<p><button type="submit">Сравнить</button></p>
</form>
<?php
if ($isPosted && !$isValid) {
echo '<p>Заполните оба поля числами.</p>';
}
if ($isValid) {
if ($a > $b) {
echo '<p>' . $a . ' больше ' . $b . '</p>';
} elseif ($a < $b) {
echo '<p>' . $a . ' меньше ' . $b . '</p>';
} else {
echo '<p>' . $a . ' равно ' . $b . '</p>';
}
}
?>
</body>
</html>
Что здесь нового:
$_SERVER['REQUEST_METHOD'] === 'POST'— форма отправлена именно сейчас; при обычном заходе методом будет'GET';- значения полей подставляются обратно в атрибут
value— после отправки форма не очищается, удобно исправить опечатку; htmlspecialchars()экранирует спецсимволы (например,<превращается в<) — текст, введённый пользователем, не сможет «сломать» разметку страницы;is_numeric()проверяет, что в полях числа (документация): это и валидация, и защита — сравнение сработает корректно.
Зачем экранировать: маленький эксперимент
Введите в поле A значение <b>5</b> и отправьте форму: страница ответит «Заполните оба поля числами» — это действительно не число, — а в поле останется ровно тот текст, который вы ввели, вместе с «тегами». А теперь уберите из атрибута value вызов htmlspecialchars() и повторите: разметка поля «поедет», потому что введённый тег станет частью страницы. Запомните правило: всё, что пришло от пользователя и выводится в HTML, сначала прогоняем через htmlspecialchars().
Что произошло на самом деле
Простой заход на страницу — это GET-запрос: REQUEST_METHOD равен 'GET', $_POST пуст. Нажатие кнопки формы — POST-запрос: REQUEST_METHOD равен 'POST', а данные из тела запроса PHP уже разложил в $_POST. Теперь наш скрипт явно различает эти две ситуации, а не гадает по isset().
Попробуйте сами
- отправьте форму с одним пустым полем: увидите подсказку, а заполненное поле сохранит значение;
- введите в поле слово «семь» — убедитесь, что сообщение о числах сработает;
- отправьте 3 и 3 — ветка
elseпо-прежнему на месте; - посложнее: добавьте третье поле и найдите наибольшее из трёх чисел — теперь с сохранением значений после отправки.
Итоги
$_SERVER['REQUEST_METHOD']точно отвечает на вопрос «отправлена ли форма»;valueплюсhtmlspecialchars()— поля не очищаются и не ломают разметку;- валидация данных (например,
is_numeric()) обязательна до любой работы с ними.
В следующем уроке разнесём форму и её обработчик по разным файлам — и научимся после обработки возвращать посетителя на исходную страницу с помощью редиректа.
- Log in to post comments
- 6 reads