Wykryto działanie AdBlocka!

Prawdopodobnie masz właczonego Adblocka. Korzystanie z bloga jest całkowicie darmowe. Jeśli jednak chcesz docenić prace autora, wyłacz blokowanie reklam dla tej witryny, aby jeszcze bardziej zmotywowac autora do dalszej pracy oraz częstszej publikacji artykułów.

Dziękuje :)

Treść główna bloga

Artykuły

System rejestracji i logowania


Logo języka PHPKażdy początkujący programista PHP chociaż raz próbował zrobić swój własny system rejestracji i logowania w oparciu o daną bazę danych, np. MySQL. Krok po kroku dowiesz się jak powinna wyglądać struktura takiego skryptu. W tym tutorialu został on napisany kodem proceduralnym, jednak lepiej napisać jest go od nowa za pomocą OOP.

Kod na Githubie

Zacznijmy od przedstawienia struktury plików:

  1. index.php – główny plik
  2. database.php – plik zawierający kod jak utworzyć bazę danych
  3. form.php – plik z formularzem rejestracji
  4. config.php – zmienne konfiguracyjne
  5. user.sql – skrypt tworzący tabele w PhpMyAdmin
  6. logout.php – wylogowywanie użytkownika
  7. register.php – plik rejestrujący użytkownika w bazie danych
  8. login.php – plik z formularzem logowania
  9. userpanel.php – plik z dostępem tylko dla zalogowanych
  10. checkuser.php – sprawdzanie czy użytkownik istnieje w bazie
  11. style.css – plik ze stylami

1. form.php:
Plik ten zawiera formularz, poprzez który nowi użytkownicy mogą się rejestrować w systemie.
W kodzie mamy taką linijkę.

2. config.php
W tym pliku znajduje się tablica z danymi, które są używane do połączenie z bazą danych.

3. database.php
Plik gdzie można pobrać plik user.sql, w którym znajduje się kod odpowiedzialny za stworzenie tabeli user. Kod ten również można pozyskać otwierając samodzielnie plik user.sql z katalogu z plikami systemu.

Uwaga: Musisz sam stworzyć bazę danych w swoim PHPMyAdmin.

4. index.php
Główny plik, który ukaże się nam podczas użytkowania skryptu.

5. logout.php
Plik, który zawiera kod odpowiedzialny za wylogowanie użytkownika.

Wygląda on następująco:

Na początku sprawdza czy istnieją zmienne sesyjne: nick oraz IP.
Jeżeli istnieją – wtedy za pomocą funkcji:
session_unset() – niszczy wszystkie zmienne sesyjne wraz z kluczem sesji.
Następnie jeśli wszystko przebiegło pomyślnie pojawi się napis „Wylogowano”.

6. login.php
Znajduje się tu formularz logowania.
Tak jak w pliku form.php też jest ?login=true, które sprawdza czy nastąpiła akcja logowania.

7. register.php

Plik odpowiedzialny za rejestracje użytkownika.

Na początku sprawdzamy, czy nastąpiło wysłanie formularza. Jeśli tak, do tworzymy krótsze zmienne i przypisujemy je do odpowiednich pól z formularza. Potem są dwa warunki, które sprawdzają, czy wszystkie pola formularze są niepuste:

oraz czy adres E-mail jest poprawny:

Następnie następuje dołączenie(ang. include) pliku config.php z tablicą, która zawiera dane potrzebne do połączenia z bazą danych.

Jeżeli wszystkie dane się zgadzają następuje połączenie z bazą danych – MySQL – za pomocą

Jeżeli, któraś z funkcji nie powiedzie się pojawi się odpowiedni komunikat o błędzie.

Potem mamy przygotowanie ciągu podanego przez użytkownika do dodania do bazy danych.

  1. trim() usuwa wszystkie spacje z ciągu znaków. Przykładowo mając ciąg: Ala ma kota, zmieni to na Alamakota
  2. mysqli_real_escape_string() zabezpiecza przez atakami typu SQL Injection
  3. strip_tags() – usuwa wszystkie znaczniki HTML. Przykładowo użytkownik chciał aby jego nick był pogrubiony więc podał <b>Nick </b>. Funkcja ma za zadanie usunąć znaczniki <b></b>.
  4. hash() – hashuje hasła, jako pierwszy parametr podaje się algorytm hashujący a jako drugi parametr ciąg do zakodowania.

Po filtracji danych następuje dodanie do bazy danych za pomocą funkcji $mysqli -> query().

Przykładowo wygląda to tak:

$result -> num_rows == 1 sprawdza czy do bazy został dodany jeden rekord. Jeżeli tak się stało wyświetla się komunikat o powodzeniu rejestracji.

Plik checkuser.php

Część kodu aż do zapytania została wyjaśniona w objaśnieniu pliku: register.php.
Teraz przechodzimy od razu do zapytania:

Ma ono za zadanie pobrać z bazy danych login oraz IP logującego się użytkownika. Wybranie tych danych następuje po tym jak użytkownik poda właściwe login i hasło.

Ten kod sprawdza czy podany użytkownik istnieje w bazie danych.

Rozpoczynamy sesję na początku pliku oraz przypisujemy do zmiennych sesyjnych odpowiadające nim rekordy z bazy danych.

Poza tym wysyłamy ciastko do przeglądarki ustanawiające maksymalny czas zalogowania – time() + 3600 czyli 1h

Jeżeli wszystko poszło dobrze przekierowujemy użytkownika na podstronę userpanel.php przeznaczoną tylko dla zalogowanych użytkowników.

Plik userpanel.php

Na samym początku dokumentu definiujemy rozpoczęcie sesji oraz funkcję ob_start(); – zabezpiecza ona nas przez błędami typu headers already send by

Na samym początku właściwego kodu sprawdzamy czy wysłane wcześniej ciastko istnieje.
W przypadku gdy nie istnieje to przekierowujemy użytkownika na podstronę z formularzem logowania.
Potem sprawdzamy czy zmienne sesyjne takie jak $_SESSION[‚nick’] i $_SESSION[‚ip’] istnieją. Jeżeli tak wyświetla się tekst: „Treść dla zalogowanych” oraz pokazuje nas się link umożliwiający wylogowanie się.

Jeżeli brak sesji pokazuje nam się link, który prowadzi do formularza logowania.

  • Super ;)Na pewno Przyda się .

  • Artur

    Mam mały problem

    Fatal error: Call to a member function bind_param() on a non-object in C:\WebServ\httpd\register.php on line 70

    $stmt = $mysqli -> prepare("INSERT INTO user(id_user, login,password,email,added,ip) VALUES('', ? , ? , ? , now(), ?)");

    Jak by ktoś pomógł byłbym wdzięczny

    • Musisz sprawdzić czy obiekty $mysqli na pewno jest dostępny.

  • Robert

    Bardzo dobry skrypt. Brawo! Mam jednak uwagę: jak widzę skrypt pozwala na dodanie do bazy danych dwóch użytkowników o tym samym loginie (Odpytanie istniejących loginów użyte jest tylko podczas logowania się). Może by przy tworzeniu nowego konta dodać odpytanie, czy dany login jest już w użyciu, czy też nie?
    Pozdrawiam!

    • Jak najbardziej dodatnie takiej funkcjonalności jest możliwe i łatwe do zaimplementowania.

      • Robert

        To wiem 🙂 Myślałem tylko, aby w następnej wersji już coś takiego dodać. Dopisał bym jedną linijkę (no dobrze, dwie… 🙂 ) odpytania więcej w checkuser.php – dla osób, które nie znają php byłoby to na pewno pomocne. Ale mimo to uważam, że skrypt jest naprawdę fajny – wyróżnia się wśród tego, co można znaleźć w necie.

        Pozdrawiam raz jeszcze!

      • Robert

        Sorry, miałem na myśli register.php 🙂

        • Miałem już zrobiony ten system w oparciu o OOP, czyli na obiektach, jednak nieoczekiwane problemy z dyskiem i po skrypcie 🙁 mimo wszystko kiedyś napiszę również na OOP 🙂

  • Daw

    jak dodać odpytanie, czy dany login jest już w użyciu, czy też nie? chciałbym aby nie można było zarejestrować 2 kont o tej samej nazwie.

  • Daw

    jak zrobić żeby użytkownik mógł dodać jedno zdjęcie i żeby inni użytkownicy mogli na nie głosować.

    • Aby uzyskać taki efekt musisz zapisać w bazie jakieś dane identyfikujące użytkownika użytkownika, np. IP, treść $_SERVER[‚HTTP_USER_AGENT’], dodatkowo możesz zainteresować się evercookie i po tych danych sprawdzać zapytaniem z poleceniem count(id) czy podany użytkownik istnieje.

      • Daw

        Nie miałem nigdy kontaktu z bazami danych wiem tylko tyle że przechowują one dane użytkowników. Nie mam pojęcia co gdzie dodać żeby to zadziałało bez błędów na stronie. Potrzebuje skryptu dokładnie takiego jaki tu jest chodzi o logowanie i rejestracje dobrze by było jak by było jeszcze:
        -brak możliwości rejestracji o tym samym loginie
        -dodawanie przynajmniej jednego zdjęcia przez użytkowników i wyświetlenie ich losowo na głównej stronie.
        -możliwość oceniania np od 1 do 6 zdjęć które będą losowo pokazywane na głównej stronie.

        takie mam zaliczenie na egzamin – proszę o pomoc 😀

        Pozdrawiam

        • Odpowiedź na twój komentarz wysyłałem drogą mailową, na E-mail podany przez ciebie w formularzu.

        • Robert

          Tutaj mały przykład – trzeba go trochę dopasować:

          mysql_connect(‚localhost’,’test’,”) or die(mysql_error());
          mysql_select_db(‚test’) or die(mysql_error());

          $login = „robert”;

          $sql = „SELECT login FROM user WHERE login=’$login’”;
          $result = mysql_query($sql);
          $count = mysql_num_rows($result);
          if ($count == 0)
          {
          echo „Login jest wolny”;
          }
          else
          {
          echo „Login jest zajety”;
          }

          Co do zdjęcia, to jest to trochę więcej pracy. Może w niedzielę wieczorem coś podeślę, chwilowo nie jestem przy kompie. Ale jeżeli chodzi o ew. zaliczenia to sugerowałbym namówienie prowadzącego zajęcia na coś lżejszego niż czysty PHP. Jakiś framework albo… RoR.

          Pozdrawiam!

          • Kod teoretycznie jest poprawny, ale proszę powiedz mi kto dziś używa zdeprecjonowanych funkcji mysql_*, kolejnym błędem jest brak jakichkolwiek zabezpieczeń. Mimo wszystko proponuje OOP i PDO 🙂

      • Robert

        Po co komplikować – przecież przy każdym użytkowniku jest już zapisywany login. Wystarczy tylko w pliku register.php przed dodaniem nowego użytkownika odpytać, czy w tabeli ‚user’ jest już podawany login.

        Pozdrawiam, czekając na obiecaną wersję obiektową 😀

    • Robert

      Masz na myśli Awarta przypisanego do danego konta, czy raczej coś w stylu galerii, gdzie zamieszcza się zdjęcia dla wszystkich użytkowników? I czy głosy maja oddawać tylko zarejestrowani, czy też każdy odwiedzający stronę?

      • Daw

        Więc tak.
        -strona główna
        -strona logowania
        -strona rejestracji
        -panel użytkownika

        wyświetlane losowo obrazki z możliwością ich komentowania.

        wiadomo. możliwość logowania się już zarejestrowanych użytkowników.

        brak możliwości rejestracji o tym samym loginie. możliwość rejestracji nowych użytkowników

        po zalogowaniu się już na swoje konto-> możliwość dodania tylko jednego zdjęcia przez użytkownika. możliwość podglądu ile zdobyło się głosów.
        ————————-
        szukałem gotowego skryptu i znalazłem ale on nie działa pokazuje jakieś błędy nazywa się Sexytop – PHP Photo Rater v1.3. Szukałem też klona strony lustereczko.pl ale nie ma. Te dwa skrypty są idealne na zaliczenie mają wszystko co potrzeba 😀 bo który nauczyciel się kapnie że to jakiś gotowiec a wiadomo zaliczenie ważne 😀 mój nauczyciel to na lekcjach filmy ogląda albo gra w Minecrafta więc taki pomysł przejdzie 😀

        Pozdrawiam

        • Według mnie szukanie skryptów w internecie do tak prostych działań to lekka przesada tym bardziej, że można to szybko napisać samemu.

        • Robert

          Przyjmuję wszystkie zarzuty Mixseta (szczególnie te dotyczące bezpieczeństwa ale:
          chłopakowi zależało na zaliczeniu zajęć, potrzebuje więc czegoś prostego. Jak widać nie zna php (lub słabo), więc wykonanie postawionego przed nim zadania jest niewykonalne. Oczywiście nie popieram kopiowania pomysłów (w końcu warto zrobić coś samemu) ale czasami zadanie przerasta człowieka, a terminy tuż, tuż.

          Więc, NAJPROŚCIEJ jest dodać w kodzie linijkę odpytującą, czy dany login jest już w użyciu. Działający kod wygląda tak (plik register.php):

          $login_test = $mysqli -> query(„SELECT login FROM user WHERE login = ‚$login'”);

          if($login_test -> num_rows == 1)
          die(‚Login jest już zajęty’);

          trzeba dodać go za linijką 52 ($ip = $_SERVER[‚REMOTE_ADDR’];)

          Jeżeli chodzi o wczytywanie plików graficznych (i to z możliwością ich oceny) to opisuje to np artykuł tutaj:

          http://4programmers.net/PHP/Przechowywanie_zdj%C4%99%C4%87_w_bazie_danych

          a ja osobiście polecam stronę pana Włodzimierza Gajdy. Jego uwagi pomogły mi z powodzeniem rozwiązać kilka problemów. Strona http://phppp.gajdaw.pl zawiera również przykładowy kod wielu rozwiązań, chociaż książki nie są za drogie i warto mieć je pod ręką.

          Ostatnia uwaga do Dawa: sugerując użycie frameworku nie miałem na myśli szukania gotowych rozwiązań. Framworki są to gotowe biblioteki, które ułatwiają tworzenie aplikacji. Wiele z nich narzuca obiektowość i dba o bezpieczeństwo, co zadowoli Mixeta. Tylko potrzeba trochę czasu, żeby się z nimi zapoznać. Najszybciej – tak sadzę – można zacząć pracę nie z PHP a z Ruby, stąd wzmianka o RoR.

          Pozdrawiam wszystkich serdecznie!

          • Już z Dawem załatwiliśmy tą sprawę 😉 A co do frameworka to w tym przypadku nie budujemy przecież drugiego onetu czy innej strony tego pokroju, żeby wykorzystywać frameworki, typu Zend, Symfony, czy nawet Kohana. Druga sprawa jest taka, że dowiedziałem się, że jego profesor jest wymagający więc zwykły kod strukturalny raczej nie wystarczy.

          • Daw

            Dzięki „Robert” za wyczerpującą odpowiedź. php znam słabo jeżeli chodzi o bazy danych to wcale a profesor nie rozumie że czegoś nie można rozumieć. Założę się że jak bym mu kazał złożyć wzmacniacz mocy audio to nie wiedział by o co chodzi.

      • Daw

        dzisiaj znalazłem system głosowania ale nie działa 🙁
        http://tutorialzine.com/2014/01/nodejs-picture-voting-game-part-2/

        • Używania node.js do tego skryptu to przerost formy nad treścią 😀 tego typu skrypty działają na zasadzie zwiększania liczby rekordu o 1.

  • Bohdan

    Cześć, ogółem bardzo ciekawy blog, bo zawiera wiele ciekawostek, które na pewno wykorzystam przy swoich eksperymentach z php i mysql i innymi takimi. Wrzuciłem skryptotekę na localhost, opisałem config danymi, którymi miałby posługiwać się dany skrypt, lecz po kliku w zaloguj wywala mi:

    Fatal error: Class 'mysqli' not found in C:\WebServ\httpd\checkuser.php on line 50

    Dane wypisane w configu są poprawne, więc w czym leży problem?

    Próbowałem wgrać nowy pliczek libmySQL.dll (jak ktoś gdzieś na forum radził) lecz to nic nie dało.

    • Najlepiej napisz do mnie na gg:28630239, coś wymyślimy 🙂