[PHP] System rejestracji

Ten artykuł ma za zadanie przybliżyć kierunek pisania systemu rejestracji użytkowników. Oczywiście będzie to prosty skrypt, który każdy sobie rozbuduje wedle swojego uznania. W skrypcie wykorzystamy sterownik PDO do komunikacji z bazą danych. Osobny artykuł będzie poświęcony systemowi logowania.

Zaczniemy od formularza rejestracyjnego:

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8" />
 
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css" type="text/css" media="screen" />
 
 <title>Rejestracja</title>
</head>
<body>
 <div class="container">
  <h1>Rejestracja</h1>
  <form action="" method="post">
   <div class="form-group">
    <p><label for="username">Nazwa użytkownika</label><input type="text" name="username" id="username" class="form-control" placeholder="Nazwa użytkownika" required /></p>
   </div>
   <div class="form-group">
    <p><label for="email">E-mail</label><input type="email" name="email" id="email" class="form-control" placeholder="E-mail" required /></p>
   </div>
   <div class="form-group">
    <p><label for="password">Hasło</label><input type="password" name="password" id="password" class="form-control" placeholder="Hasło" required /></p>
   </div>
   <div class="form-group">
    <p><label for="repeated_password">Powtórz hasło</label><input type="password" name="repeated_password" id="repeated_password" class="form-control" placeholder="Powtórz hasło" required /></p>
   </div>
   <p><input type="submit" class="btn btn-primary" value="Zarejestruj" /></p>
  </form>
 </div>
</body>
</html>
Formularz ostylowany Bootstrapem bez żadnych fajerwerków graficznych. W razie potrzeby każdy sobie go upiększy po swojemu. Jeśli chodzi o pola to chyba nie muszę tłumaczyć, które do czego służy.

Utworzenie tabeli z odpowiednimi kolumnami

W tym kroku utworzymy zapytanie SQL tworzące tabelę users, w której będziemy przechowywać rekordy z użytkownikami:

CREATE TABLE IF NOT EXISTS `users` (
 `id` int(10) NOT NULL AUTO_INCREMENT,
 `registered_timestamp` int(10) NOT NULL,
 `username` varchar(30) NOT NULL,
 `email` varchar(50) NOT NULL,
 `password` varchar(255) NOT NULL,
 `ip` varchar(100) NOT NULL,
 PRIMARY KEY (`id`)
 );
Powyższe zapytanie można wykonać w phpMyAdmin lub z poziomu skryptu:
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);

$dbh->exec("CREATE TABLE IF NOT EXISTS `users` (
 `id` int(10) NOT NULL AUTO_INCREMENT,
 `registered_timestamp` int(10) NOT NULL,
 `username` varchar(30) NOT NULL,
 `email` varchar(50) NOT NULL,
 `password` varchar(255) NOT NULL,
 `ip` varchar(100) NOT NULL,
 PRIMARY KEY (`id`)
 )");
Opiszę pokrótce kolumny tabeli users:
  • id - unikalny ID użytkownika;
  • registered_timestamp - data rejestracji w formie timestampu;
  • username - nazwa użytkownika;
  • email - email użytkownika;
  • password - hasło użytkownika;
  • ip - IP, z którego utworzono konto;

Połączenie z bazą danych

Teraz pora na utworzenie pliku set-db-connection.php, w którym ustawimy połączenie z bazą MySQL poprzez sterownik PDO:

$dbh = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');

Skrypt rejestracji

Na tym etapie będziemy tworzyć już właściwy kod odpowiadający za rejestrację użytkownika. Będzie to strona registration.php zawierająca utworzony już wcześniej formularz połączony z kodem PHP oraz klasa User:

<?php

 ini_set('display_errors', '1');
 
 error_reporting(E_ALL);
 
 if(!isset($_POST['username'])):
 
?>

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8" />
 
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css" type="text/css" media="screen" />
 
 <title>Rejestracja</title>
</head>
<body>
 <div class="container">
  <h1>Rejestracja</h1>
  <form action="" method="post">
   <div class="form-group">
    <p><label for="username">Nazwa użytkownika</label><input type="text" name="username" id="username" class="form-control" placeholder="Nazwa użytkownika" required /></p>
   </div>
   <div class="form-group">
    <p><label for="email">E-mail</label><input type="email" name="email" id="email" class="form-control" placeholder="E-mail" required /></p>
   </div>
   <div class="form-group">
    <p><label for="password">Hasło</label><input type="password" name="password" id="password" class="form-control" placeholder="Hasło" required /></p>
   </div>
   <div class="form-group">
    <p><label for="repeated_password">Powtórz hasło</label><input type="password" name="repeated_password" id="repeated_password" class="form-control" placeholder="Powtórz hasło" required /></p>
   </div>
   <p><input type="submit" class="btn btn-primary" value="Zarejestruj" /></p>
  </form>
 </div>
</body>
</html>

<?php else: ?>

<?php

if(!empty($_POST['username']) && !empty($_POST['email']) && !empty($_POST['password'])) {

 $username = preg_replace('/[^\p{L}\p{N}]/iu', '', $_POST['username']);
 $email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
 $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
 $ip = filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP);
 
 if(strlen($_POST['username']) >= 3) {
 
  if(strlen($_POST['username']) <= 30) {
  
   if(strlen($_POST['email']) >= 6) {
   
    if(strlen($_POST['email']) <= 30) {
    
     if(strlen($_POST['password']) >= 6) {
     
      if(strlen($_POST['password']) <= 16) {
      
       if(hash_equals($_POST['password'], $_POST['repeated_password'])) {
       
        require 'set-db-connection.php';
        require 'class.user.php';
        
        $user = new User($dbh);
        
        if(!$user->user_exist($username, $email)) {
        
         if($user->insert_user($username, $email, $password, $ip)) {
         
          echo '<p>Konto zostało założone.</p>';
          
         }
         
         else {
         
          echo '<p>Nie udało się zarejestrować.</p>';
          
         }
         
        }
        
        else {
        
         echo '<p>Taki użytkownik już istnieje.</p>';
         
        }
        
       }
       
       else {
       
        echo '<p>Hasła się nie zgadzają.</p>';
        
       }
       
      }
      
      else {
      
       echo '<p>Hasło jest zbyt długie.</p>';
       
      }
      
     }
     
     else {
     
      echo '<p>Hasło jest zbyt krótkie.</p>';
      
     }
     
    }
    
    else {
    
     echo '<p>E-mail jest zbyt długi.</p>';
     
    }
    
   }
   
   else {
   
    echo '<p>E-mail jest zbyt krótki.</p>';
    
   }
   
  }
  
  else {
  
   echo '<p>Nazwa użytkownika jest zbyt długa.</p>';
   
  }
  
 }
 
 else {
 
  echo '<p>Nazwa użytkownika jest zbyt krótka.</p>';
  
 }
 
}

else {

 echo '<p>Wypełnij wszystkie pola, aby się zarejestrować.</p>';
 
}

?>

<?php endif; ?>

Klasa User

Tworzymy teraz plik class.user.php z klasą User. Będzie ona na tą chwilę zawierała metodę sprawdzającą czy dany użytkownik istnieje oraz metodę zapisu użytkownika do bazy.

<?php

 class User {
 
  function __construct($dbh) {
  
   $this->dbh = $dbh;
   
  }
  
  public function user_exist($username, $email) {
  
   $sth = $this->dbh->prepare('SELECT id FROM users WHERE username = :username OR email = :email LIMIT 1');
   
   $sth->bindParam(':username', $username, PDO::PARAM_STR);
   $sth->bindParam(':email', $email, PDO::PARAM_STR);
   
   $sth->execute();
   
   return $sth->fetch(PDO::FETCH_ASSOC);
   
  }
  
  public function insert_user($username, $email, $password, $ip) {
  
   $sth = $this->dbh->prepare("INSERT INTO users (id, registered_timestamp, username, email, password, ip) VALUES('', CURRENT_TIMESTAMP(), :username, :email, :password, :ip)");
   
   $sth->bindParam(':username', $username, PDO::PARAM_STR);
   $sth->bindParam(':email', $email, PDO::PARAM_STR);
   $sth->bindParam(':password', $password, PDO::PARAM_STR);
   $sth->bindParam(':ip', $ip, PDO::PARAM_STR);
   
   return $sth->execute();
   
  }
  
 }

To na tyle, jeśli zrobiłeś wszystko zgodnie z tym artykułem, rejestracja użytkowników powinna działać. Jeśli są jakieś pytania lub sugestie, proszę pisać je w komentarzach.

Aktualna wersja skryptu dostępna jest na GitHub.

Komentarze

Popular

[HTML] Jak wstawić obrazek?

[PHP|HTML] Odświeżenie strony

[HTML] Jak wycentrować stronę?