Обработка данных форм на PHP: полное руководство с примерами

Раздел: Обработка данных на PHP -> Отправка данных форм

Основы отправки форм в PHP

Обработка данных формы на стороне сервера начинается с выбора метода отправки (GET или POST) и настройки атрибутов action и method в HTML. Наиболее эффективное решение предполагает использование $_POST для получения данных, их фильтрацию и валидацию, а также защиту от межсайтовой подделки запросов (CSRF).

Базовый обработчик формы (POST)


<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $name = trim($_POST['name'] ?? '');
    $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
    if ($name && $email) {
        // дальнейшая обработка (сохранение, отправка письма)
        echo 'Данные получены: ' . htmlspecialchars($name) . ', ' . htmlspecialchars($email);
    } else {
        echo 'Ошибка валидации';
    }
}
?>
<form method="post">
    <input type="text" name="name" required>
    <input type="email" name="email" required>
    <button type="submit">Отправить</button>
</form>

отправка форм php (отправка форм в php)

При заполнении полей и отправке: Данные получены: Иван, ivan@example.com

Этот пример проверяет метод запроса, очищает ввод от лишних пробелов и проверяет email. Фильтрация через filter_input предотвращает некорректные данные. htmlspecialchars защищает от XSS при выводе.

Когда использовать GET вместо POST?

GET подходит для нечувствительных данных и поисковых запросов. Данные передаются в URL. Пример:


<form method="get" action="search.php">
    <input type="text" name="q">
    <button>Поиск</button>
</form>

В PHP данные доступны через $_GET['q']. Ограничение: длина URL (около 2000 символов).

Типичная ошибка: использование GET для логинов или паролей – они видны в истории браузера и логах сервера. Решение: всегда POST для конфиденциальных данных.

Как обработать загрузку файлов?

Для файлов требуется атрибут enctype="multipart/form-data". Обработка через $_FILES:


<form method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <button>Загрузить</button>
</form>
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $file = $_FILES['file'];
    if ($file['error'] === UPLOAD_ERR_OK) {
        move_uploaded_file($file['tmp_name'], 'uploads/' . basename($file['name']));
        echo 'Файл загружен';
    }
}
?>

Проблема: не проверено расширение и MIME-тип. Злоумышленник может загрузить PHP-скрипт. Решение: проверять mime_content_type и расширение, ограничивать размер через upload_max_filesize в php.ini.

Как отправить форму через AJAX?

Это позволяет не перезагружать страницу. Пример на fetch с JSON:


// JavaScript
fetch('handler.php', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({name: 'Анна', email: 'anna@test.com'})
}).then(r => r.text()).then(console.log);

<?php
// handler.php
$data = json_decode(file_get_contents('php://input'), true);
echo 'Получено: ' . htmlspecialchars($data['name']);
?>
Вывод в консоли: Получено: Анна

Ошибка: забывают установить заголовок Content-Type в fetch. Без него PHP не сможет прочитать JSON из php://input. Решение: явно указывать заголовок.

Как защитить форму от CSRF?

Создать токен, хранить в сессии, вставить в форму скрытое поле. На сервере сравнить:


<?php
session_start();
if (empty($_SESSION['csrf'])) $_SESSION['csrf'] = bin2hex(random_bytes(32));
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!hash_equals($_SESSION['csrf'], $_POST['csrf'] ?? '')) {
        die('CSRF атака');
    }
    // обработка
}
?>
<form method="post">
    <input type="hidden" name="csrf" value="<?= $_SESSION['csrf'] ?>">
    <!-- поля -->
</form>

Проблема: токен не обновляется после отправки. Для критичных операций лучше генерировать новый токен после каждого использования.

Как отправить письмо с данными формы?

Использовать mail() или PHPMailer (для вложений и SMTP). Простейший пример:


<?php
if ($_POST['submit']) {
    $to = 'admin@site.com';
    $subject = 'Новая заявка';
    $message = 'Имя: ' . $_POST['name'] . '\nEmail: ' . $_POST['email'];
    $headers = 'From: no-reply@site.com' . "\r\n" . 'Reply-To: ' . $_POST['email'];
    mail($to, $subject, $message, $headers);
}
?>

Типичная ошибка: заголовки инъекции через переносы строк в поле email. Решение: проверять email фильтром и удалять нежелательные символы.

Как обработать массив полей формы?

Имена полей с квадратными скобками name="items[]" создают массив:


<input type="text" name="items[]" value="1">
<input type="text" name="items[]" value="2">
<?php print_r($_POST['items']); // Array([0]=>1,[1]=>2) ?>

Ошибка: если поле необязательное, при отсутствии отправки элемента индекс может сместиться. Решение: проверять через isset или array_filter.

Расширенные примеры обработки форм

1. Форма с проверкой капчи (Google reCAPTCHA v3)

Пример

<form method="post">
    <input type="text" name="name" required>
    <button type="submit" class="g-recaptcha" data-sitekey="ваш_ключ" data-action="submit">Отправить</button>
</form>
<script src="https://www.google.com/recaptcha/api.js"></script>
<?php
if ($_POST) {
    $recaptcha = $_POST['g-recaptcha-response'] ?? '';
    $secret = 'ваш_секрет';
    $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=$secret&response=$recaptcha");
    $responseKeys = json_decode($response, true);
    if (intval($responseKeys["score"]) >= 0.5) {
        echo 'Капча пройдена, имя: ' . htmlspecialchars($_POST['name']);
    } else {
        echo 'Вы бот';
    }
}
?>
При успешной проверке: Капча пройдена, имя: Иван

2. Сохранение данных формы в базу данных через PDO

Пример

<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (:name, :email)');
    $stmt->execute([
        ':name' => htmlspecialchars($_POST['name']),
        ':email' => filter_var($_POST['email'], FILTER_SANITIZE_EMAIL)
    ]);
    echo 'Пользователь добавлен с ID: ' . $pdo->lastInsertId();
}
?>
<form method="post">
    <input type="text" name="name" required>
    <input type="email" name="email" required>
    <button>Сохранить</button>
</form>
Пользователь добавлен с ID: 5

3. Обработка JSON-данных с множественными полями

Пример

// JSON отправляется из клиента:
// fetch('api.php', {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({user:{name:'Петр', skills:['PHP','JS']}})})

<?php
$input = json_decode(file_get_contents('php://input'), true);
if (isset($input['user']['name'])) {
    $name = htmlspecialchars($input['user']['name']);
    $skills = implode(', ', array_map('htmlspecialchars', $input['user']['skills'] ?? []));
    echo "Имя: $name, навыки: $skills";
}
?>
Имя: Петр, навыки: PHP, JS

4. Отправка формы с загрузкой нескольких файлов

Пример

<form method="post" enctype="multipart/form-data">
    <input type="file" name="files[]" multiple>
    <button>Загрузить</button>
</form>
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['files'])) {
    foreach ($_FILES['files']['tmp_name'] as $index => $tmp) {
        if ($_FILES['files']['error'][$index] === UPLOAD_ERR_OK) {
            $ext = pathinfo($_FILES['files']['name'][$index], PATHINFO_EXTENSION);
            if (in_array(strtolower($ext), ['jpg','png','gif'])) {
                move_uploaded_file($tmp, 'uploads/' . uniqid() . '.' . $ext);
                echo 'Файл ' . $_FILES['files']['name'][$index] . ' загружен. ';
            } else {
                echo 'Недопустимый формат: ' . $_FILES['files']['name'][$index] . ' ';
            }
        }
    }
}
?>
Файл photo1.jpg загружен. Файл photo2.png загружен. Недопустимый формат: script.php

5. AJAX-отправка с валидацией на стороне сервера и возвратом JSON

Пример

// JavaScript
const formData = new FormData(document.querySelector('form'));
fetch('ajax_handler.php', {
    method: 'POST',
    body: formData
}).then(r => r.json()).then(data => {
    if (data.success) alert('OK'); else alert(data.error);
});

// ajax_handler.php
<?php
$errors = [];
if (empty($_POST['name'])) $errors[] = 'Имя обязательно';
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if (!$email) $errors[] = 'Некорректный email';

if (empty($errors)) {
    echo json_encode(['success' => true, 'message' => 'Все хорошо']);
} else {
    echo json_encode(['success' => false, 'error' => implode(', ', $errors)]);
}
?>
При пустом имени и неверном email: {"success":false,"error":"Имя обязательно, Некорректный email"}

6. Обработка формы с проверкой уникальности email в БД

Пример

<?php
$pdo = new PDO('sqlite:users.db');
$pdo->exec('CREATE TABLE IF NOT EXISTS users (email TEXT PRIMARY KEY, name TEXT)');

if ($_POST) {
    $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
    if (!$email) die('Неверный email');

    $stmt = $pdo->prepare('SELECT 1 FROM users WHERE email = ?');
    $stmt->execute([$email]);
    if ($stmt->fetch()) {
        echo 'Email уже зарегистрирован';
    } else {
        $stmt = $pdo->prepare('INSERT INTO users (email, name) VALUES (?, ?)');
        $stmt->execute([$email, htmlspecialchars($_POST['name'])]);
        echo 'Регистрация успешна';
    }
}
?>
Если email уже существует: Email уже зарегистрирован

Отправка форм в PHP - comments

En
отправка форм php (php)