КаталогBuilderPHPDocs

Глава 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-защиту и понятную обработку ошибок.