[PHP] System rejestracji
Ten artykuł ma na celu przybliżyć kierunek pisania systemu rejestracji użytkowników. Oczywiście będzie to prosty skrypt, który każdy sobie rozbuduje wedle swoich potrzeb. W skrypcie wykorzystamy sterownik PDO do komunikacji z bazą danych. System logowania zostanie stworzony w osobnym wpisie.
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:
$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 także na GitHub.
Fatal error: Uncaught Error: Call to a member function bindParam() on bool in C:\xampp\htdocs\SportsCounter\html\class.user.php:37 Stack trace: #0 C:\xampp\htdocs\SportsCounter\html\rejestracja2.php(72): User->user_exist('test', 'test@mail.com') #1 {main} thrown in C:\xampp\htdocs\SportsCounter\html\class.user.php on line 37
OdpowiedzUsuńzmieniłam bazę na usersnew, podmieniłam w kodzie, mimo to gdzieś istnieje błąd, a w tabeli nie mam takiego samego użytkownika jak wskazywałby error, pomożesz?