Урок 20

Форма регистрации

30 мин

Что нужно для регистрации?

  1. HTML-форма с полями (имя, email, пароль)
  2. Валидация данных (проверка на корректность)
  3. Проверка, что пользователь не существует
  4. Хеширование пароля
  5. Сохранение в базу данных

Почему нужно хешировать пароли?

Хранить пароли в открытом виде — преступление.

Если хакер получит доступ к базе, он увидит все пароли. А люди часто используют один пароль везде...

Хеширование — это преобразование пароля в нечитаемую строку:

Пароль: "secret123"
Хеш: "$2y$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy"

Из хеша нельзя восстановить пароль. Можно только проверить: "этот пароль даёт такой же хеш?"

PHP имеет встроенные функции:

  • password_hash($password, PASSWORD_DEFAULT) — создать хеш
  • password_verify($password, $hash) — проверить пароль

Создаём страницу регистрации

Создайте файл public/register.php:

<?php
require_once "includes/config.php";

// Если пользователь уже авторизован — редирект на главную
if (isset($_SESSION["user_id"])) {
    header("Location: index.php");
    exit;
}

$page_title = "Регистрация — $site_name";
$errors = [];
$success = false;

// Значения полей (для сохранения при ошибке)
$username = "";
$email = "";

// Обработка формы
if ($_SERVER["REQUEST_METHOD"] === "POST") {
    
    // Получаем данные
    $username = trim($_POST["username"] ?? "");
    $email = trim($_POST["email"] ?? "");
    $password = $_POST["password"] ?? "";
    $password_confirm = $_POST["password_confirm"] ?? "";
    
    // Валидация username
    if (empty($username)) {
        $errors[] = "Введите имя пользователя";
    } elseif (strlen($username) < 3) {
        $errors[] = "Имя пользователя должно быть минимум 3 символа";
    } elseif (strlen($username) > 50) {
        $errors[] = "Имя пользователя слишком длинное";
    } elseif (!preg_match('/^[a-zA-Z0-9_]+$/', $username)) {
        $errors[] = "Имя пользователя может содержать только латинские буквы, цифры и _";
    }
    
    // Валидация email
    if (empty($email)) {
        $errors[] = "Введите email";
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $errors[] = "Некорректный формат email";
    }
    
    // Валидация пароля
    if (empty($password)) {
        $errors[] = "Введите пароль";
    } elseif (strlen($password) < 6) {
        $errors[] = "Пароль должен быть минимум 6 символов";
    }
    
    // Проверка подтверждения пароля
    if ($password !== $password_confirm) {
        $errors[] = "Пароли не совпадают";
    }
    
    // Проверка уникальности
    if (empty($errors)) {
        $existingUser = getUserByLogin($username);
        if ($existingUser) {
            $errors[] = "Пользователь с таким именем уже существует";
        }
        
        $existingEmail = getUserByLogin($email);
        if ($existingEmail) {
            $errors[] = "Пользователь с таким email уже существует";
        }
    }
    
    // Если ошибок нет — создаём пользователя
    if (empty($errors)) {
        $userId = createUser($username, $email, $password);
        
        if ($userId) {
            $success = true;
            // Очищаем форму
            $username = "";
            $email = "";
        } else {
            $errors[] = "Ошибка при создании пользователя";
        }
    }
}

include "includes/header.php";
?>

<h2>Регистрация</h2>

<?php if ($success): ?>
    <div style="background: #d4edda; border: 1px solid #c3e6cb; padding: 20px; border-radius: 8px; margin-bottom: 20px;">
        <strong>Регистрация успешна!</strong><br>
        Теперь вы можете <a href="login.php">войти в систему</a>.
    </div>
<?php endif; ?>

<?php if (!empty($errors)): ?>
    <div style="background: #f8d7da; border: 1px solid #f5c6cb; padding: 20px; border-radius: 8px; margin-bottom: 20px;">
        <strong>Ошибки:</strong>
        <ul style="margin: 10px 0 0 20px;">
            <?php foreach ($errors as $error): ?>
                <li><?= escape($error) ?></li>
            <?php endforeach; ?>
        </ul>
    </div>
<?php endif; ?>

<form method="POST" style="max-width: 400px;">
    <div style="margin-bottom: 15px;">
        <label style="display: block; margin-bottom: 5px; font-weight: bold;">Имя пользователя:</label>
        <input 
            type="text" 
            name="username" 
            value="<?= escape($username) ?>"
            placeholder="Только латинские буквы и цифры"
            style="width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box;"
            required
        >
    </div>
    
    <div style="margin-bottom: 15px;">
        <label style="display: block; margin-bottom: 5px; font-weight: bold;">Email:</label>
        <input 
            type="email" 
            name="email" 
            value="<?= escape($email) ?>"
            placeholder="example@mail.ru"
            style="width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box;"
            required
        >
    </div>
    
    <div style="margin-bottom: 15px;">
        <label style="display: block; margin-bottom: 5px; font-weight: bold;">Пароль:</label>
        <input 
            type="password" 
            name="password" 
            placeholder="Минимум 6 символов"
            style="width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box;"
            required
        >
    </div>
    
    <div style="margin-bottom: 20px;">
        <label style="display: block; margin-bottom: 5px; font-weight: bold;">Подтвердите пароль:</label>
        <input 
            type="password" 
            name="password_confirm" 
            placeholder="Повторите пароль"
            style="width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box;"
            required
        >
    </div>
    
    <button 
        type="submit"
        style="width: 100%; background: #F36049; color: white; padding: 12px; border: none; border-radius: 4px; font-size: 16px; cursor: pointer;"
    >
        Зарегистрироваться
    </button>
</form>

<p style="margin-top: 20px;">
    Уже есть аккаунт? <a href="login.php">Войти</a>
</p>

<?php include "includes/footer.php"; ?>

Разбор кода

Редирект для авторизованных

if (isset($_SESSION["user_id"])) {
    header("Location: index.php");
    exit;
}

Если пользователь уже вошёл, зачем ему регистрация? Перенаправляем.

Сохранение значений полей

value="<?= escape($username) ?>"

Если была ошибка, пользователю не нужно заново вводить имя и email.

preg_match для валидации

preg_match('/^[a-zA-Z0-9_]+$/', $username)

Регулярное выражение проверяет, что в строке только разрешённые символы.

Проверьте регистрацию

  1. Откройте http://localhost:8080/register.php
  2. Попробуйте отправить пустую форму — увидите ошибки
  3. Введите короткий пароль — ошибка
  4. Заполните всё правильно — успех!
  5. Проверьте в phpMyAdmin таблицу users — новый пользователь там!
Регистрация готова!
В следующем уроке создадим форму входа.

Мы используем файлы cookie для улучшения работы сайта и персонализации контента. Продолжая использовать сайт, вы соглашаетесь с использованием cookies в соответствии с нашей Политикой конфиденциальности.