Обработка данных форм на PHP
Обработка форм в PHP: основные подходы и примеры
Современный способ обработки формы подразумевает использование суперглобального массива $_POST в сочетании с функциями фильтрации и проверкой CSRF токена. Пример базовой обработки:
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['csrf_token']) && hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($name && $email) {
// сохранение данных
header('Location: success.php');
exit;
} else {
$error = 'Некорректные данные';
}
}
Пояснение:
- Проверяется метод запроса POST.
- CSRF токен сравнивается с токеном в сессии.
filter_inputочищает и проверяет данные.- После успеха выполняется редирект для предотвращения повторной отправки.
Типичная ошибка: отсутствие проверки CSRF приводит к уязвимости «межсайтовой подделки запросов». Решение: генерировать уникальный токен и хранить в сессии.
Как обработать форму с помощью простого POST запроса без CSRF?
Для простых внутренних форм можно использовать прямую проверку $_POST:
$name = $_POST['name'] ?? '';
$email = $_POST['email'] ?? '';
if (empty($name) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = 'Заполните все поля корректно';
} else {
// обработка
}
Проблема: данные не фильтруются, возможна XSS-атака при выводе. Рекомендуется использовать htmlspecialchars при выводе.
Как организовать поиск по сайту через GET форму?
GET запрос удобен для поиска, так как параметры видны в URL и могут быть добавлены в закладки. Пример:
$query = $_GET['q'] ?? '';
$query = trim(strip_tags($query));
// поиск в базе данных
Ошибка: слишком длинный URL может быть обрезан сервером. Ограничьте длину запроса или используйте POST для длинных строк.
Как отправить форму через Ajax с ответом в формате JSON?
Это позволяет обновлять часть страницы без перезагрузки. Пример на PHP:
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
header('Content-Type: application/json');
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);
if (!$name) {
echo json_encode(['status' => 'error', 'message' => 'Имя обязательно']);
exit;
}
echo json_encode(['status' => 'success', 'message' => 'Спасибо, ' . htmlspecialchars($name)]);
exit;
}
Проблема: при отключенном JavaScript форма не отправится. Необходимо предусмотреть fallback на обычную отправку.
Как загрузить файл через форму?
Форма должна иметь enctype='multipart/form-data'. Пример обработки:
if ($_FILES['avatar']['error'] === UPLOAD_ERR_OK) {
$ext = pathinfo($_FILES['avatar']['name'], PATHINFO_EXTENSION);
$allowed = ['jpg', 'png', 'gif'];
if (in_array($ext, $allowed)) {
move_uploaded_file($_FILES['avatar']['tmp_name'], 'uploads/' . uniqid() . '.' . $ext);
} else {
$error = 'Недопустимый тип файла';
}
}
Типичные ошибки: превышение лимита размера файла (настройка upload_max_filesize и post_max_size), загрузка исполняемых файлов. Необходимо проверять MIME-тип и расширение.
Расширенные примеры обработки форм
Форма регистрации с валидацией и хэшированием пароля
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$errors = [];
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$password = $_POST['password'] ?? '';
if (!$username || strlen($username) < 3) $errors[] = 'Имя минимум 3 символа';
if (!$email) $errors[] = 'Некорректный email';
if (strlen($password) < 6) $errors[] = 'Пароль минимум 6 символов';
if (empty($errors)) {
$hash = password_hash($password, PASSWORD_DEFAULT);
// insert into database
$success = true;
}
}
if (!empty($errors)) {
foreach ($errors as $e) echo '' . htmlspecialchars($e) . '
';
} else if ($success) {
echo 'Регистрация успешна
';
}
Обработка массива полей (несколько телефонов)
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$phones = $_POST['phones'] ?? [];
foreach ($phones as $phone) {
$phone = filter_var($phone, FILTER_SANITIZE_NUMBER_INT);
// валидация и сохранение
}
}
print_r($phones);
Загрузка файла с записью в лог
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($_FILES['document']['error'] === UPLOAD_ERR_OK) {
$name = $_FILES['document']['name'];
$tmp = $_FILES['document']['tmp_name'];
$target = 'uploads/' . basename($name);
if (move_uploaded_file($tmp, $target)) {
$size = filesize($target);
$log = 'Файл ' . $name . ' загружен, размер ' . $size . ' байт';
} else {
$log = 'Ошибка перемещения файла';
}
} else {
$log = 'Ошибка загрузки';
}
}
echo $log;