Przejdź do treści

Rejestracja użytkowników z password_hash()

  • Użytkownicy i logowanie
  • poziom: średni
  • aktualizacja: 12 lipca 2026

Rejestracja użytkowników to pierwszy krok do serwisu z kontami. Najważniejsza zasada: haseł nigdy nie zapisujemy w postaci jawnej — do bazy trafia tylko hasz wygenerowany funkcją password_hash(), którego nie da się „odwrócić".

Skrypt tworzy komplet: formularz, walidację, kontrolę unikalności adresu e-mail i zapis konta. Pasuje do niego skrypt „Logowanie użytkowników".

PHP 121 linii Pobierz .php
<?php
/**
 * Rejestracja użytkowników — skryptyPHP.com
 * Zapisz jako: rejestracja.php
 *
 * Tabela użytkowników:
 *   CREATE TABLE uzytkownicy (
 *       id         INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
 *       email      VARCHAR(190) NOT NULL UNIQUE,
 *       haslo_hash VARCHAR(255) NOT NULL,
 *       imie       VARCHAR(100) NOT NULL,
 *       utworzono  DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
 *   ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_polish_ci;
 */

session_start();
require 'baza.php'; // skrypt „Połączenie z bazą (PDO)"

$pdo   = polacz_z_baza();
$bledy = [];
$dane  = ['imie' => '', 'email' => ''];
$zarejestrowano = false;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $dane['imie']  = trim($_POST['imie'] ?? '');
    $dane['email'] = mb_strtolower(trim($_POST['email'] ?? ''));
    $haslo         = $_POST['haslo']  ?? '';
    $haslo2        = $_POST['haslo2'] ?? '';

    // ── Walidacja ───────────────────────────────────────────
    if ($dane['imie'] === '' || mb_strlen($dane['imie']) > 100) {
        $bledy[] = 'Podaj imię (do 100 znaków).';
    }
    if (!filter_var($dane['email'], FILTER_VALIDATE_EMAIL)) {
        $bledy[] = 'Podaj poprawny adres e-mail.';
    }
    if (mb_strlen($haslo) < 8) {
        $bledy[] = 'Hasło musi mieć co najmniej 8 znaków.';
    }
    if ($haslo !== $haslo2) {
        $bledy[] = 'Hasła nie są identyczne.';
    }

    // ── Czy e-mail jest wolny? ──────────────────────────────
    if (!$bledy) {
        $stmt = $pdo->prepare('SELECT id FROM uzytkownicy WHERE email = ?');
        $stmt->execute([$dane['email']]);
        if ($stmt->fetch()) {
            $bledy[] = 'Konto z tym adresem e-mail już istnieje.';
        }
    }

    // ── Zapis konta ─────────────────────────────────────────
    if (!$bledy) {
        // password_hash sam generuje sól i wybiera mocny algorytm
        $hash = password_hash($haslo, PASSWORD_DEFAULT);

        $stmt = $pdo->prepare(
            'INSERT INTO uzytkownicy (email, haslo_hash, imie) VALUES (?, ?, ?)'
        );
        $stmt->execute([$dane['email'], $hash, $dane['imie']]);

        $zarejestrowano = true;
        $dane = ['imie' => '', 'email' => ''];
    }
}
?>
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Rejestracja</title>
<style>
    .formularz { max-width: 420px; font-family: sans-serif; margin: 20px auto; }
    .formularz label { display: block; margin: 12px 0 4px; font-weight: bold; }
    .formularz input { width: 100%; padding: 8px; box-sizing: border-box; }
    .formularz button { margin-top: 16px; padding: 10px 24px; cursor: pointer; }
    .bledy  { color: #b00020; }
    .sukces { color: #1b7a2f; font-weight: bold; }
</style>
</head>
<body>

<form class="formularz" method="post" action="">
    <h2>Załóż konto</h2>

    <?php if ($zarejestrowano): ?>
        <p class="sukces">Konto utworzone! Możesz się teraz
            <a href="logowanie.php">zalogować</a>.</p>
    <?php endif; ?>

    <?php if ($bledy): ?>
        <ul class="bledy">
            <?php foreach ($bledy as $blad): ?>
                <li><?= htmlspecialchars($blad) ?></li>
            <?php endforeach; ?>
        </ul>
    <?php endif; ?>

    <label for="imie">Imię</label>
    <input type="text" id="imie" name="imie" required
           value="<?= htmlspecialchars($dane['imie']) ?>">

    <label for="email">E-mail</label>
    <input type="email" id="email" name="email" required
           value="<?= htmlspecialchars($dane['email']) ?>">

    <label for="haslo">Hasło (min. 8 znaków)</label>
    <input type="password" id="haslo" name="haslo" required
           minlength="8" autocomplete="new-password">

    <label for="haslo2">Powtórz hasło</label>
    <input type="password" id="haslo2" name="haslo2" required
           minlength="8" autocomplete="new-password">

    <button type="submit">Zarejestruj się</button>
</form>

</body>
</html>

Jak użyć tego skryptu

  1. Utwórz tabelę uzytkownicy zapytaniem z komentarza na górze skryptu.
  2. Podłącz plik baza.php (skrypt „Bezpieczne połączenie z bazą MySQL") i zapisz kod jako rejestracja.php.
  3. Dodaj do kompletu skrypt „Logowanie użytkowników" — korzysta z tej samej tabeli.
  4. Kolumna haslo_hash musi mieć długość VARCHAR(255) — nowe algorytmy haszowania mogą generować dłuższe hasze niż obecne 60 znaków.

Warto wiedzieć

  • password_hash($haslo, PASSWORD_DEFAULT) automatycznie dobiera bezpieczny algorytm (obecnie bcrypt) i losową sól — nie używaj md5() ani sha1() do haseł, to od lat złamane rozwiązania.
  • Adres e-mail sprowadzamy do małych liter, a kolumna ma indeks UNIQUE — razem eliminuje to duplikaty kont.
  • W realnym serwisie warto dodać potwierdzenie adresu e-mail linkiem aktywacyjnym (tokeny generuj przez random_bytes() jak w skrypcie „Resetowanie hasła").
  • Nie zdradzaj w komunikatach więcej, niż trzeba — u nas informacja „konto istnieje" jest jawna, ale w serwisach wymagających prywatności lepiej wysłać e-mail zamiast pokazywać ten komunikat.
#rejestracja #password_hash #konto #pdo #bezpieczeństwo

Podobne skrypty