Глава 8. Формы, GET и POST в PHP
Большинство динамических сайтов работает с пользовательским вводом: поиск, регистрация, комментарии, заявки, фильтры каталога и формы обратной связи. В PHP такие данные обычно приходят через массивы $_GET и $_POST. На первый взгляд это простая тема, но именно здесь чаще всего появляются ошибки безопасности.
Чем отличаются GET и POST
GET передаёт параметры в адресной строке. Его удобно использовать для поиска, фильтров, пагинации и любых действий, которые не изменяют данные на сервере.
POST передаёт данные в теле запроса. Он подходит для регистрации, отправки комментариев, сохранения настроек и других действий, которые меняют состояние системы.
<form method="get" action="/search.php">
<input type="text" name="q">
<button type="submit">Найти</button>
</form>
Чтение данных формы
Перед использованием значения нужно проверить, существует ли оно. Простой способ — оператор объединения с null.
$query = $_GET['q'] ?? '';
$name = $_POST['name'] ?? '';
Но этого мало. Если значение должно быть числом, его нужно привести к числу. Если это строка, её нужно обрезать и проверить длину.
$page = isset($_GET['page']) ? (int) $_GET['page'] : 1;
$email = trim($_POST['email'] ?? '');
Валидация
Валидация отвечает на вопрос: подходит ли значение по смыслу. Например, email должен быть похож на email, возраст — быть числом, текст комментария — не быть пустым.
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'Некорректный email';
}
if (mb_strlen($name) < 2) {
$errors[] = 'Имя слишком короткое';
}
Экранирование вывода
Даже если данные проверены, при выводе в HTML их нужно экранировать через htmlspecialchars(). Это защищает страницу от XSS-атак.
echo htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
CSRF-защита
Если форма изменяет данные, ей нужен CSRF-токен. Смысл простой: сервер создаёт случайное значение, кладёт его в сессию и добавляет в скрытое поле формы. При отправке формы значение сверяется.
$_SESSION['csrf'] = bin2hex(random_bytes(16));
<input type="hidden" name="csrf" value="<?= htmlspecialchars($_SESSION['csrf']) ?>">
Обработка ошибок
Хорошая форма не просто сообщает «ошибка», а показывает конкретные причины. Пользователь должен понимать, что исправить: email, пароль, текст или обязательное поле.
Практический пример
session_start();
$name = trim($_POST['name'] ?? '');
$message = trim($_POST['message'] ?? '');
$errors = [];
if (mb_strlen($name) < 2) {
$errors[] = 'Укажите имя';
}
if (mb_strlen($message) < 10) {
$errors[] = 'Сообщение слишком короткое';
}
if (!$errors) {
// сохранить сообщение в базу данных
}
Типичные ошибки
- Использовать GET для удаления или изменения данных.
- Выводить значения формы без htmlspecialchars().
- Проверять только наличие поля, но не его формат.
- Не использовать CSRF-защиту для важных действий.
- Доверять скрытым полям формы как надёжным данным.
Итоги
Формы — это граница между пользователем и приложением. Всё, что приходит из $_GET и $_POST, нужно проверять. Правильная работа с формами включает чтение данных, валидацию, экранирование вывода, CSRF-защиту и понятную обработку ошибок.