Logowanie i rejestracja w PHP
System logowania i rejestracji to praktycznie najważniejszy element strony www.
Na początek stworzymy sobie plik config.php. Będą się w nim znajdować dane do połączenia z bazą danych oraz niezbędne funkcje:
połączenie i rozłączenie z mysql
filtrowanie danych
kodowanie hasła
sprawdzenie czy użytkownik jest zalogowany
pobranie danych użytkownika
<?php
// definiujemy dane do połączenia z bazą danych
define('DBHOST', 'localhost');
define('DBUSER', 'root');
define('DBPASS', '');
define('DBNAME', 'baza');
function db_connect() {
// połączenie z mysql
mysql_connect(DBHOST, DBUSER, DBPASS) or die('<h2>ERROR</h2> MySQL Server is not responding');
// wybór bazy danych
mysql_select_db(DBNAME) or die('<h2>ERROR</h2> Cannot connect to specified database');
}
function db_close() {
mysql_close();
}
function clear($text) {
// jeśli serwer automatycznie dodaje slashe to je usuwamy
if(get_magic_quotes_gpc()) {
$text = stripslashes($text);
}
$text = trim($text); // usuwamy białe znaki na początku i na końcu
$text = mysql_real_escape_string($text); // filtrujemy tekst aby zabezpieczyć się przed sql injection
$text = htmlspecialchars($text); // dezaktywujemy kod html
return $text;
}
function codepass($password) {
// kodujemy hasło (losowe znaki można zmienić lub całkowicie usunąć
return sha1(md5($password).'#!%Rgd64');
}
// funkcja na sprawdzanie czy user jest zalogowany, jeśli nie to wyświetlamy komunikat
function check_login() {
if(!$_SESSION['logged']) {
die('<p>To jest strefa tylko dla użytkowników.</p>
<p>[<a href="login.php">Logowanie</a>] [<a href="register.php">Zarejestruj się</a>]</p>');
}
}
// funkcja na pobranie danych usera
function get_user_data($user_id = -1) {
// jeśli nie podamy id usera to podstawiamy id aktualnie zalogowanego
if($user_id == -1) {
$user_id = $_SESSION['user_id'];
}
$result = mysql_query("SELECT * FROM `users` WHERE `user_id` = '{$user_id}' LIMIT 1");
if(mysql_num_rows($result) == 0) {
return false;
}
return mysql_fetch_assoc($result);
}
// startujemy sesje
// jeśli nie ma jeszcze sesji "logged" i "user_id" to wypełniamy je domyślnymi danymi
if(!isset($_SESSION['logged'])) {
$_SESSION['logged'] = false;
$_SESSION['user_id'] = -1;
}
?>
Gdy już mamy plik konfiguracyjny należy stworzyć tabelę w bazie danych.
CREATE TABLE `users` (
`user_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_name` varchar(255) NOT NULL,
`user_password` varchar(40) NOT NULL,
`user_email` varchar(255) NOT NULL,
`user_regdate` int(10) UNSIGNED NOT NULL,
`user_from` varchar(255) NOT NULL,
`user_website` varchar(255) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Zapytanie wklejamy do phpMyAdmin lub tworzymy sobie prosty skrypt, który wykona za nas tę czynność:
<?php
include 'config.php';
db_connect();
mysql_query("CREATE TABLE `users` (
`user_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(255) NOT NULL,
`user_password` varchar(40) NOT NULL,
`user_email` varchar(255) NOT NULL,
`user_regdate` int(10) unsigned NOT NULL,
`user_from` varchar(255) NOT NULL,
`user_website` varchar(255) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;");
db_close();
?>
Pierwszym krokiem będzie stworzenie formularza do rejestracji i logowania. Na początek plik register.php:
<?php
include 'config.php';
db_connect();
// sprawdzamy czy user nie jest przypadkiem zalogowany
if(!$_SESSION['logged']) {
// jeśli zostanie naciśnięty przycisk "Zarejestruj"
if(isset($_POST['name'])) {
// filtrujemy dane...
$_POST['name'] = clear($_POST['name']);
$_POST['password'] = clear($_POST['password']);
$_POST['password2'] = clear($_POST['password2']);
$_POST['email'] = clear($_POST['email']);
// sprawdzamy czy wszystkie pola zostały wypełnione
if(empty($_POST['name']) || empty($_POST['password']) || empty($_POST['password2']) || empty($_POST['email'])) {
echo '<p>Musisz wypełnić wszystkie pola.</p>';
// sprawdzamy czy podane dwa hasła są takie same
} elseif($_POST['password'] != $_POST['password2']) {
echo '<p>Podane hasła różnią się od siebie.</p>';
// sprawdzamy poprawność emaila
} elseif(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) === false) {
echo '<p>Podany email jest nieprawidłowy.</p>';
} else {
// sprawdzamy czy są jacyś uzytkownicy z takim loginem lub adresem email
$result = mysql_query("SELECT Count(user_id) FROM `users` WHERE `user_name` = '{$_POST['name']}' OR `user_email` = '{$_POST['email']}'");
$row = mysql_fetch_row($result);
if($row[0] > 0) {
echo '<p>Już istnieje użytkownik z takim loginem lub adresem e-mail.</p>';
} else {
// jeśli nie istnieje to kodujemy haslo...
$_POST['password'] = codepass($_POST['password']);
// i wykonujemy zapytanie na dodanie usera
mysql_query("INSERT INTO `users` (`user_name`, `user_password`, `user_email`, `user_regdate`) VALUES ('{$_POST['name']}', '{$_POST['password']}', '{$_POST['email']}', '".time()."')");
echo '<p>Zostałeś poprawnie zarejestrowany! Możesz się teraz <a href="login.php">zalogować</a>.</p>';
}
}
}
// wyświetlamy formularz
echo '<form method="post" action="register.php">
<p>
Login:<br>
<input type="text" value="'.$_POST['name'].'" name="name">
</p>
<p>
Hasło:<br>
<input type="password" value="'.$_POST['password'].'" name="password">
</p>
<p>
Powtórz hasło:<br>
<input type="password" value="'.$_POST['password2'].'" name="password2">
</p>
<p>
E-mail:<br>
<input type="text" value="'.$_POST['email'].'" name="email">
</p>
<p>
<input type="submit" value="Zarejestruj">
</p>
</form>';
} else {
echo '<p>Jesteś już zalogowany, więc nie możesz stworzyć nowego konta.</p>
<p>[<a href="index.php">Powrót</a>]</p>';
}
db_close();
?>
Następnie plik login.php:
<?php
include 'config.php';
db_connect();
// sprawdzamy czy user nie jest przypadkiem zalogowany
if(!$_SESSION['logged']) {
// jeśli zostanie naciśnięty przycisk "Zaloguj"
if(isset($_POST['name'])) {
// filtrujemy dane...
$_POST['name'] = clear($_POST['name']);
$_POST['password'] = clear($_POST['password']);
// i kodujemy hasło
$_POST['password'] = codepass($_POST['password']);
// sprawdzamy prostym zapytaniem sql czy podane dane są prawidłowe
$result = mysql_query("SELECT `user_id` FROM `users` WHERE `user_name` = '{$_POST['name']}' AND `user_password` = '{$_POST['password']}' LIMIT 1");
if(mysql_num_rows($result) > 0) {
// jeśli tak to ustawiamy sesje "logged" na true oraz do sesji "user_id" wstawiamy id usera
$row = mysql_fetch_assoc($result);
$_SESSION['logged'] = true;
$_SESSION['user_id'] = $row['user_id'];
echo '<p>Zostałeś poprawnie zalogowany! Możesz teraz przejść na <a href="index.php">stronę główną</a>.</p>';
} else {
echo '<p>Podany login i/lub hasło jest nieprawidłowe.</p>';
}
}
// wyświetlamy komunikat na zalogowanie się
echo '<form method="post" action="login.php">
<p>
Login:<br>
<input type="text" value="'.$_POST['name'].'" name="name">
</p>
<p>
Hasło:<br>
<input type="password" value="'.$_POST['password'].'" name="password">
</p>
<p>
<input type="submit" value="Zaloguj">
</p>
</form>';
} else {
echo '<p>Jesteś już zalogowany, więc nie możesz się zalogować ponownie.</p>
<p>[<a href="index.php">Powrót</a>]</p>';
}
db_close();
?>
Nieodłącznym elementem naszego skryptu musi być plik index.php który będzie sprawdzał czy user jest zalogowany. Jeśli nie to wyświetli linki do logowania lub rejestracji - w przeciwnym wypadku powita użytkownika oferując mu zobaczenie tajnej zawartości ;)
<?php
include 'config.php';
db_connect();
check_login();
// pobieramy dane usera
$user_data = get_user_data();
echo '<p>Witaj <b>'.$user_data['user_name'].'</b>!</p>
<p>Jesteś w strefie tylko dla zalogowanych.</p>
<p>[<a href="profile.php?id='.$user_data['user_id'].'">Wyświetl swój profil</a>] [<a href="editprofile.php">Edytuj profil</a>] [<a href="userlist.php">Lista użytkowników</a>] [<a href="logout.php">Wyloguj się</a>]</p>';
db_close();
?>
Jak widać w powyższym pliku zalogowany użytkownik ma dostęp do kilku opcji. Zaczniemy od wylogowania, ponieważ ten plik jest najkrótszy. logout.php:
<?php
$_SESSION['logged'] = false;
$_SESSION['user_id'] = -1;
header('Location: index.php');
?>
Ustawiamy sesje "logged" na false i usuwamy id usera, po czym następuje przekierowanie na index.php.
Teraz czas na "dodatki" :) Na początek edycja profilu - editprofile.php:
<?php
include 'config.php';
db_connect();
check_login();
$user_data = get_user_data();
// jeśli zostanie naciśnięty przycisk "Edytuj profil"
if(isset($_POST['email'])) {
// filtrujemy dane
$_POST['website'] = clear($_POST['website']);
$_POST['from'] = clear($_POST['from']);
$_POST['new_password'] = clear($_POST['new_password']);
$_POST['new_password2'] = clear($_POST['new_password2']);
$_POST['password'] = clear($_POST['password']);
$_POST['email'] = clear($_POST['email']);
// zmienne tymczasowe na treść błędu
$err = '';
// i zapytanie sql
$up2 = '';
// jeśli zostanie podane nowe hasło lub inny email
if(!empty($_POST['new_password']) || $_POST['email'] != $user_data['user_email']) {
// sprawdzamy czy zostało podane aktualne hasło
if(empty($_POST['password'])) {
$err = '<p>Jeśli chcesz zmienić hasło lub adres email musisz podać aktualne hasło.</p>';
// jeśli zostało podane to sprawdzamy czy jest poprawne
} elseif(codepass($_POST['password']) != $user_data['user_password']) {
$err = '<p>Podane aktualne hasło jest nieprawidłowe.</p>';
} else {
// jeśli wszystko jest ok...
// sprawdzamy czy user chce zmienić hasło
if(!empty($_POST['new_password'])) {
// jeśli podane dwa hasła są różne to wyświetlamy błąd
if($_POST['new_password'] != $_POST['new_password2']) {
$err = '<p>Podane hasła nie są takie same.</p>';
// jeśli wszystko jest ok, dopisujemy do zmiennej tymczasowej zapytanie do zaktualizowania hasła
} else {
$up2.= ", `user_password` = '".codepass($_POST['new_password'])."'";
}
}
// sprawdzamy czy user chce zmienić email (czy ten podany jest różny od aktualnego)
if($_POST['email'] != $user_data['user_email']) {
// sprawdzamy czy podany email jest prawidłowy
if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) === false) {
$err = '<p>Podany email jest nieprawidłowy.</p>';
} else {
// sprawdzamy czy istnieje taki email w bazie przy czym omijamy usera który jest zalogowany
$result = mysql_query("SELECT Count(user_id) FROM `users` WHERE `user_id` != '{$user_data['user_id']}' AND `user_email` = '{$_POST['email']}'");
$row = mysql_fetch_row($result);
if($row[0] > 0) {
$err = '<p>Już istnieje użytkownik z takim loginem lub adresem e-mail.</p>';
} else {
// jeśli wszystko jest ok to dopisujemy zapytanie do zaktualizowania emaila
$up2.= ", `user_email` = '{$_POST['email']}'";
}
}
}
}
}
// jeśli są jakieś błędy z powyższych działań to je wyświetlamy
if(!empty($err)) {
echo $err;
} else {
// jeśli nie ma błędów to wykonujemy zapytanie dopisując te na aktualizacje hasła oraz emaila - $up2
$result = mysql_query("UPDATE `users` SET `user_website` = '{$_POST['website']}', `user_from` = '{$_POST['from']}'{$up2} WHERE `user_id` = '{$user_data['user_id']}'");
if($result) {
// jeśli zapytanie się wykonało to wyświetlamy komunikat...
echo '<p>Twój profil został poprawnie zaktualizowany.</p>';
// i pobieramy od nowa dane usera aby w poniższym formularze się one zaktualizowały
$user_data = get_user_data();
} else {
// jeśli zapytanie będzie błędne to wyświetlamy treść errora
echo '<p>Niestety wystąpił błąd:<br>'.mysql_error().'</p>';
}
}
}
// wyświetlamy prosty formularz
echo '<form method="post" action="editprofile.php">
<p>
Login:<br>
<input type="text" value="'.$user_data['user_name'].'" disabled="true">
</p>
<p>
Strona WWW:<br>
<input type="text" value="'.$user_data['user_website'].'" name="website">
</p>
<p>
Skąd:<br>
<input type="text" value="'.$user_data['user_from'].'" name="from">
</p>
<p>
Nowe hasło (pozostaw puste jeśli nie chcesz zmieniać):<br>
<input type="password" value="" name="new_password" autocomplete="off">
</p>
<p>
Powtórz nowe hasło:<br>
<input type="password" value="" name="new_password2" autocomplete="off">
</p>
<p>
E-mail:<br>
<input type="text" value="'.$user_data['user_email'].'" name="email">
</p>
<p>
Aktualne hasło (wymagane przy zmianie emaila lub hasła):<br>
<input type="password" value="" name="password" autocomplete="off">
</p>
<p>
<input type="submit" value="Edytuj profil">
</p>
</form>';
db_close();
?>
Wyświetlanie profilu - profile.php:
<?php
include 'config.php';
db_connect();
check_login();
// filtrujemy id oraz rzutujemy je na int
$_GET['id'] = (int)clear($_GET['id']);
// pobieramy dane usera z podanego id
$user_data = get_user_data($_GET['id']);
// sprawdzamy czy znalazło użytkownika
// jeśli nie to wyświetlamy komunikat
// a jeśli tak to wyświetlamy wszystkie jego dane
// jeśli user nie ma podanej strony www lub skąd jest to wyświetlamy "brak"
if($user_data === false) {
echo '<p>Niestety, taki użytkownik nie istnieje.</p>
<p>[<a href="index.php">Powrót</a>]</p>';
} else {
echo '<h2>Profil użytkownika</h2>
<p>Nick: <b>'.$user_data['user_name'].'</b></p>
<p>Email: '.$user_data['user_email'].'</p>
<p>Data rejestracji: '.date("d.m.Y, H:i", $user_data['user_regdate']).'</p>
<p>Strona WWW: '.(empty($user_data['user_website']) ? 'brak' : $user_data['user_website']).'</p>
<p>Skąd: '.(empty($user_data['user_from']) ? 'brak' : $user_data['user_from']).'</p>';
}
db_close();
?>
Oraz wyświetlanie listy wszystkich użytkowników - userlist.php.
<?php
include 'config.php';
db_connect();
check_login();
// wyświetlamy początek prostej tabelki
echo '<h2>Lista użytkowników</h2>
<table border="1" width="500px">
<tr>
<th>Nick</th>
<th>Email</th>
<th>Data rejestracji</th>
</tr>';
// sprawdzamy ilu jest wszystkich userów
$result = mysql_query("SELECT Count(user_id) FROM `users`");
$row = mysql_fetch_row($result);
$count_users = $row[0];
// ustawiamy ile ma być wyników na 1 strone
$per_page = 10;
// obliczamy ilość stron
$pages = ceil($count_users / $per_page);
// aktualna strona - jeśli nie została podana to = 1
// jeśli została podana to filtrujemy ją i rzutujemy na int
$current_page = !isset($_GET['page']) ? 1 : (int)clear($_GET['page']);
// jeśli ktoś poda stronę mniejszą niż 1 lub większą niż ilość stron to zmieniamy ją na 1
if($current_page < 1 || $current_page > $pages) {
$current_page = 1;
}
// jeśli jest chociaż 1 user to wyświetlamy
if($count_users > 0) {
$result = mysql_query("SELECT * FROM `users` ORDER BY `user_id` ASC LIMIT ".($per_page*($current_page-1)).", ".$per_page);
while($row = mysql_fetch_assoc($result)) {
echo '<tr>
<td><a href="profile.php?id='.$row['user_id'].'">'.$row['user_name'].'</a></td>
<td>'.$row['user_email'].'</td>
<td>'.date("d.m.Y, H:i", $row['user_regdate']).'</td>
</tr>';
}
} else {
// jeśli nie ma w ogóle to wyświetlamy komunikat
echo '<tr>
<td colspan="3" style="text-align:center">Niestety nie znaleziono żadnych użytkowników.</td>
</tr>';
}
echo '</table>';
// wyświetlamy stronicowanie
if($pages > 0) {
echo '<p>';
if($pages < 11) {
for($i = 1; $i <= $pages; $i++) {
if($i == $current_page) {
echo '<b>['.$current_page.']</b> ';
} else {
echo '<a href="userlist.php?page='.$i.'">['.$i.']</a> ';
}
}
} elseif($current_page > 10) {
echo '<a href="userlist.php?page=1">[1]</a> ';
echo '<a href="userlist.php?page=2">[2]</a> ';
echo '[...] ';
for($i = ($current_page-3); $i <= $current_page; $i++) {
if($i == $current_page) {
echo '<b>['.$current_page.']</b> ';
} else {
echo '<a href="userlist.php?page='.$i.'">['.$i.']</a> ';
}
}
for($i = ($current_page+1); $i <= ($current_page+3); $i++) {
if($i > ($pages)) break;
if($i == $current_page) {
echo '<b>['.$current_page.']</b> ';
} else {
echo '<a href="userlist.php?page='.$i.'">['.$i.']</a> ';
}
}
if($current_page < ($pages-4)) {
echo '[...] ';
echo '<a href="userlist.php?page='.($pages-1).'">['.($pages-1).']</a> ';
echo '<a href="userlist.php?page='.$pages.'">['.$pages.']</a> ';
} elseif($current_page == ($pages-4)) {
echo '[...] ';
echo '<a href="userlist.php?page='.$pages.'">['.$pages.']</a> ';
}
} else {
for($i = 1; $i <= 11; $i++) {
if($i == $current_page) {
if($i > ($pages)) break;
echo '<b>['.$current_page.']</b> ';
} else {
echo '<a href="userlist.php?page='.$i.'">['.$i.']</a> ';
}
}
if($pages > 12) {
echo '[...] ';
echo '<a href="userlist.php?page='.($pages-1).'">['.($pages-1).']</a> ';
echo '<a href="userlist.php?page='.$pages.'">['.$pages.']</a> ';
} elseif($pages == 12) {
echo '[...] ';
echo '<a href="userlist.php?page=12">[12]</a> ';
}
}
echo '</p>';
}
db_close();
?>
O czym należy pamiętać:
nie trzeba dawać wszędzie session_start() - robi to za nas plik config.php
na początku pliku zawsze trzeba dać db_connect() a na końcu db_close()
aby podstrona była tylko dla zalogowanych należy użyć funkcji check_login()
do skryptu trzeba dopisać brakujący kod html (<html><head></head><body></body></html>) oraz przerobić pod własne upodobania
skrypt jest pisany tak aby początkujący mogli zobaczyć jak zrobić prosty system logowania i rejestracji, kod wymaga dużo usprawnień