От HTML-формы до записи в базу данных на PHP
Один сквозной сценарий связывает темы форм, PDO и исключений. Без фреймворка — чтобы было видно каждый шаг.
Схема потока
Таблица и подключение
CREATE TABLE subscribers (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL,
UNIQUE KEY uq_email (email)
);
Файл bootstrap.php — общее подключение PDO (подключается из скриптов):
<?php
declare(strict_types=1);
$pdo = new PDO(
'mysql:host=127.0.0.1;dbname=app;charset=utf8mb4',
getenv('DB_USER') ?: 'app_user',
getenv('DB_PASS') ?: '',
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
],
);
Шаг 1 — форма (GET)
public/register.php:
<?php
declare(strict_types=1);
?>
<!DOCTYPE html>
<html lang="ru">
<head><meta charset="utf-8"><title>Подписка</title></head>
<body>
<h1>Подписка на рассылку</h1>
<?php if (!empty($_GET['error'])): ?>
<p role="alert">Проверьте поля и попробуйте снова.</p>
<?php endif; ?>
<form action="register_submit.php" method="post">
<label>Имя <input name="name" required maxlength="100"></label>
<label>Email <input name="email" type="email" required maxlength="255"></label>
<button type="submit">Подписаться</button>
</form>
</body>
</html>
method="post" — данные в теле запроса, не в URL. Пароли и персональные данные не передают через GET.
Шаг 2 — приём и валидация (POST)
public/register_submit.php:
<?php
declare(strict_types=1);
require dirname(__DIR__) . '/bootstrap.php';
$name = trim((string) ($_POST['name'] ?? ''));
$email = trim((string) ($_POST['email'] ?? ''));
$errors = [];
if ($name === '') {
$errors['name'] = 'Укажите имя';
} elseif (mb_strlen($name) > 100) {
$errors['name'] = 'Имя слишком длинное';
}
if ($email === '') {
$errors['email'] = 'Укажите email';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors['email'] = 'Некорректный email';
}
if ($errors !== []) {
// Упрощение: редирект с флагом; в реальном проекте — сессия с полями и ошибками
header('Location: register.php?error=1');
exit;
}
Фильтрация на сервере обязательна: клиентская проверка в браузере обходится за секунду.
Шаг 3 — запись через PDO
try {
$stmt = $pdo->prepare(
'INSERT INTO subscribers (name, email, created_at) VALUES (:name, :email, :created_at)'
);
$stmt->execute([
'name' => $name,
'email' => $email,
'created_at' => (new DateTimeImmutable('now'))->format('Y-m-d H:i:s'),
]);
} catch (PDOException $e) {
// Дубликат email (код 23000 — integrity constraint)
if ((int) ($e->errorInfo[1] ?? 0) === 1062) {
header('Location: register.php?error=duplicate');
exit;
}
error_log($e->getMessage());
http_response_code(500);
echo 'Ошибка сервера';
exit;
}
header('Location: thanks.php', true, 302);
exit;
Паттерн Post/Redirect/Get: после успешного POST браузер получает редирект на thanks.php. Обновление страницы не повторяет INSERT.
Шаг 4 — страница благодарности
public/thanks.php — статичный HTML «Спасибо за подписку». Без повторной обработки POST.
Безопасность в этом сценарии
| Угроза | Мера |
|---|---|
| SQL-инъекция | Только prepare + именованные параметры |
| XSS при выводе ошибок | htmlspecialchars($msg, ENT_QUOTES, 'UTF-8') для любого текста из POST |
| Повторная отправка формы | Редирект после успешного POST |
| CSRF | Токен в сессии и скрытое поле формы (см. сессии) |
| Перебор email | Rate limit на уровне веб-сервера или кэша |
Развитие сценария
- Вынести валидацию в класс
App\Validation\SubscribeValidator— пространства имён. - Хранить ошибки в
$_SESSIONи показывать их рядом с полями — сессии. - Статус подписки задать через enum.
- Перейти на маршрутизацию фреймворка — Laravel или Symfony.
Что изучить дальше
См. также
Другие статьи этого же раздела в боковом меню (как на странице «О разделе»). PHP как язык веб-разработки - роль серверного исполнения, базовый синтаксис и место в современном стеке. Экосистема PHP-приложений - фреймворки, инструменты, пакеты и типовые архитектурные подходы веб-разработки. PHP — это язык программирования общего назначения, который изначально создавался для динамической генерации веб-страниц. Модель исполнения PHP - жизненный цикл запроса, серверный контекст и экосистема популярных CMS. История PHP - эволюция языка от простых скриптов до зрелой платформы серверной веб-разработки. Composer в PHP - управление зависимостями, автозагрузка классов и воспроизводимая сборка проектов. Параметр opcache.fast_shutdown ускоряет завершение работы скрипта за счёт пропуска стандартной процедуры освобождения памяти. Вместо этого используется механизм сборщика мусора операционной системы. Локальная среда разработки на PHP - настройка стека, запуск приложения и отладка без продакшен-сервера. Набор советов, правил, принципов и обычаев в разработке на этом языке. Фреймворки и библиотеки PHP - организация сервисов, вспомогательные компоненты и ускорение разработки веб-приложений. Гайд по установке и настройке с написанием первой программы и её запуском. Примеры простых и полезных консольных приложений с демонстрацией концепций языка.PHP - язык веб-разработки
Экосистема PHP-приложений
Что требуется знать перед началом изучения языка программирования PHP
Модель исполнения PHP
История языка PHP
Composer - управление зависимостями в PHP
Настройка веб-сервера для работы с PHP
Локальная среда разработки на PHP
Рекомендации по разработке на PHP
Фреймворки и библиотеки PHP
Первая программа на PHP
Простые приложения на PHP