Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ Oceny _ Rejestracja i logowanie

Napisany przez: huberthx 25.11.2019, 21:14:09

Czy moglibyście zapoznać się z moim kodem rejestracji i logowania użytkowników.
Po ostatniej wpadce ze stronką chciałbym zasięgnąć opinii bardziej doświadczonych programistów, a że nie mam kogo się poradzić pisze dlatego na tym forum.
Oto kod:

  1. <?php
  2. http://www.php.net/session_start();
  3. class Uzytkownik
  4. {
  5. private $bazaDanych;
  6. //łączenie z bazą danych
  7. public function polaczZBazaDanych()
  8. {
  9. $this->bazaDanych = new mysqli('localhost','uzytkownik','haslo','bazaDanych');
  10. }
  11. //reozlaczenie z baza danych
  12. public function rozlaczZBazaDanych()
  13. {
  14. $this->bazaDanych->close();
  15. }
  16. //walidacja danych wprowadzonych przez użytkownika
  17. private function walidacja($dana)
  18. {
  19. //do uzupełnienia
  20. return $dana;
  21. }
  22. //rejestracja użytkownika
  23. public function zarejestrujUzytkownik($login,$email,$haslo1,$haslo2)
  24. {
  25. //łączenie z bazą danych
  26. $this->polaczZBazaDanych();
  27. //walidacja czterech zmiennych
  28. $login = $this->walidacja($login);
  29. $email = $this->walidacja($email);
  30. $haslo1 = $this->walidacja($haslo1);
  31. $haslo2 = $this->walidacja($haslo2);
  32. //zapytanie czy istnieje użytkownik o podanym loginie lub mailu
  33. $sqlSprawdzenieCzyIstniejeUzytkownikWBazieDanych = "SELECT * FROM uzytkownicy
  34. WHERE loginU = '".$login."' OR email = '".$email."'
  35. ";
  36. //wykonanie powyższego zapytania
  37. $rezultatSprawdzenia = $this->bazaDanych->query($sqlSprawdzenieCzyIstniejeUzytkownikWBazieDanych);
  38. //jezeli znaleziono użytkownika o takim samym loginie lub emailu
  39. if ($rezultatSprawdzenia->num_rows > 0)
  40. {
  41. http://www.php.net/echo "<span class='zle'>Użytkownik o takim samym loginie lub email-u instnieje, Rejesrtacja nie powiodła się</span>";
  42. return false;
  43. }
  44. else
  45. {
  46. //sprawdzenie czy hasła są identyczne
  47. if ($haslo1 != $haslo2)
  48. {
  49. //jeżeli nie są identyczne hasła odpowiedni komunikat
  50. http://www.php.net/echo "<span class='zle'>Hasła nie powtórzyły się</span>";
  51. return false;
  52. }
  53. //zapytanie - rejestracja użytkownika - zapisanie do bazy danych
  54. $sqlRejestracjaUzytkownik = "INSERT INTO uzytkownicy (loginU,email,haslo)
  55. VALUES ('".$login."','".$email."',SHA1('".$haslo1."'))";
  56. //wykonanie powyższego zapytania
  57. $rezultat = $this->bazaDanych->query($sqlRejestracjaUzytkownik);
  58. //jeżli rejestracja się powiodła odpowiedni komunikat
  59. if ($rezultat)
  60. http://www.php.net/echo "<span class='ok'>Zarejestrowano</span>";
  61. //jeżeli rejestracja się nie powiodła odpowiedni komunikat
  62. else
  63. http://www.php.net/echo "<span class='zle'>Rejestracja nie powiodła się</span>";
  64. }
  65. $this->rozlaczZBazaDanych();
  66. }
  67. //logowanie użytkownika
  68. public function zalogujUzytkownik($login,$haslo)
  69. {
  70. //walidacja
  71. $login = $this->walidacja($login);
  72. $haslo = $this->walidacja($haslo);
  73. //łączymy z bazą danych
  74. $this->polaczZBazaDanych();
  75. //zapytanie czy ligin i hasło się zgadzają
  76. $sqlLogowanie = "SELECT * FROM uzytkownicy WHERE
  77. loginU = '".$login."' AND haslo = SHA1('".$haslo."')";
  78. //wykonanie powyższego zapytania
  79. $rezultatLogowanie = $this->bazaDanych->query($sqlLogowanie);
  80. //jeżeli znaleziono dane o takim użytkowniku to logujemy
  81. if ($rezultatLogowanie->num_rows == 1)
  82. {
  83. $rezultatLogowanie = $rezultatLogowanie->fetch_assoc();
  84. //ustawienie sesji użytkownika - przechowuje login użytkownika
  85. $_SESSION['uzytkownik'] = $rezultatLogowanie['loginU'];
  86. //odpowiedzni komunikat po zalogowaniu
  87. http://www.php.net/echo "<span class='ok'>Zalogowano użytkownika ".$_SESSION['uzytkownik']." <a href='uzytkownik.php?akcja=wyloguj'>Wyloguj</a></span>";
  88. }
  89. else
  90. {
  91. //nie znaleziono użytkownika o takich danych - odpowiedni komunikat o tym fakcie
  92. http://www.php.net/echo "<span class='zle'>Nieudana próba logowania</span>";
  93. }//rozłączamyh z bazą danych
  94. $this->rozlaczZBazaDanych();
  95. }
  96. //wylogowywanie
  97. public function wyloguj()
  98. {
  99. //usuwanie zmiennej sesji
  100. http://www.php.net/unset($_SESSION['uzytkownik']);
  101. http://www.php.net/session_destroy();
  102. //odpowiedni komunikat informujący o wylogowaniu
  103. http://www.php.net/echo "<span class='ok'>Wylogowano</span>";
  104. }
  105. //pokazujemy info o zalogowanym użytkowniku lub o braku zalogowania
  106. public function czyZalogowano()
  107. {
  108. //w zależności o istnieniu sesji użytkownika odpowiednia informacja
  109. if (http://www.php.net/isset($_SESSION['uzytkownik']))
  110. http://www.php.net/echo "<span class='ok'>Zalogowano jako ".$_SESSION['uzytkownik']."<a href='uzytkownik.php?akcja=wyloguj' >Wyloguj</a></a></span>";
  111. else
  112. http://www.php.net/echo "<span><a href='uzytkownik.php?akcja=zalogujFormularz'>Nie jesteś zalogowany - zaloguj się</a></span>";
  113. }
  114. }
  115. ?>
  116.  

Za ocenę dziękuję

Napisany przez: viking 26.11.2019, 08:00:22

Popełniasz standardowy błąd początkujących. Opakowałeś strukturalny kod w klasę która niewiele ma wspólnego z programowanie obiektowym. Odpowiedzialność klasy: połączenie z bazą (fatalne jak już ci pisałem wcześniej), walidacja danych, funkcje widoku (echo kodu html), zarządzanie sesją. Poza tym mamy już czasy PHP7 - gdzie jakieś typowanie? Na początek poczytaj o dependency injection, PSR. Możesz to zrobić np:

  1. class UserEntity {
  2. use ArrayTrait; // metoda toArray()
  3.  
  4. private $login;
  5. private $email;
  6.  
  7. public function getLogin() : string {
  8. return $this->login;
  9. }
  10.  
  11. public function setLogin(string $login) : void {
  12. // Niektórzy tutaj dają walidację danych chociaż nie jestem zwolennikiem
  13. $this->login = $login;
  14. }
  15. }
  16.  
  17. class UserService implements UserServiceInterface {
  18.  
  19. private $storage;
  20.  
  21. public function __construct(\Pdo $storage) {
  22. $this->storage = $storage;
  23. }
  24.  
  25. public function registerUser(UserEntity $user) : bool {
  26. $this->storage->beginTransaction();
  27. try {
  28. $prep = $this->storage->prepare('INSERT INTO users...');
  29. $prep->execute($user->toArray());
  30. $this->storage->commit();
  31. return true;
  32. } catch (\PDOException $e) {
  33. // np. logowanie zdarzenia
  34. $this->storage->rollBack();
  35. return false;
  36. }
  37. }
  38. }

Napisany przez: huberthx 26.11.2019, 10:49:41

Przepraszam że nie zakładam nowego tematu ale może w tym może być.
Czy mógłby ktoś polecić jakąś dobrą książkę o OOP-ie ?

Napisany przez: gitbejbe 28.11.2019, 19:06:39

książka niewiele Ci da. Podobnie jakbyś wpisał w google "php oop" to poczytasz o strukturze klas, ewentualnie jakieś proste przykłady w dupy. Cała sztuka nie polega na tym że napiszesz Class zamiast function, tylko na zmianie w sposobie myślenia o projektowaniu kodu oraz wykorzystaniu możliwości jakie dają Tobie obiekty. Tutaj trzeba sporego doświadczenia. Na początek na pewno poczytaj o dobrych praktykach (zacznij od SOLID) i staraj sie do nich stosować. W realizacji tych praktyk pomogą Tobie wzorce projektowe (przykładowy spis: https://lukasz-socha.pl/php/wzorce-projektowe-spis-tresci/). W pewnym momencie pomyślisz o testach jednostkowych i znowu odkryjesz że Twój kod powinien wyglądać jeszcze inaczej. Wypadałoby poznac standardy kodowania (PSR). Buszuj po githubie, analizuj kody innych, zacznij korzystać z frameworków. Tak jak wspomniałem wszystko to wymaga lat praktyki, stąd też stawki jakie zarabiają starsi programiści.

ps: pamiętaj przy tym że programowanie obiektowe to tylko jeden ze sposób na rozwiązanie danego zagadnienia, nie jest wcale powiedziane że takie podejście jest zawsze właściwe a nawet pożądane

Napisany przez: Tomplus 28.11.2019, 19:38:46

Dokładnie @gitbejbe ma rację przykłady z książek zwykle nie są życiowe, ale nie oznacza to że książka się nie przyda, teraz na HELION jest promocja 2 książki w cenie 1, więc warto np. wziąć książkę o Czystym Kodzie, RC Martin. Możesz wziąć drugą o PHP o wzorcach i obiektach, przynajmniej zakodujesz sobie podstawy, łatwiej zrozumieć także Githuba, dlaczego ludzie piszą tak a nie inaczej.




Napisany przez: huberthx 29.11.2019, 18:25:17

Poczytałem i oto wynik mojej nauki i prośba o ocenę.
Przepraszam za być może nieodpowiednie nazewnictwo metod bądź składowych
Oto zarys kodu:

  1. <?php
  2.  
  3. class Db
  4. {
  5. private http://www.php.net/static $instance;
  6. private $host = 'localhost';
  7. private $username = 'uzytkownik';
  8. private $password = 'haslo';
  9. private $database = 'bazaDanych';
  10. private $connection;
  11. public http://www.php.net/static function getInstance()
  12. {
  13. if (self::$instance === null)
  14. {
  15. self::$instance = new Db();
  16. }
  17. return self::$instance;
  18. }
  19. private function __construct()
  20. {
  21. $this->connection = new mysqli($this->host,$this->username,$this->password,$this->database);
  22. }
  23. private function __clone() {}
  24. public function getConnection()
  25. {
  26. return $this->connection;
  27. }
  28. }
  29. $Db = Db::getInstance();
  30.  
  31. class Uzytkownik
  32. {
  33. private $login;
  34. private $haslo;
  35. public function setLogin($login) : void
  36. {
  37.  
  38. $this->login = $login;
  39. }
  40. public function getLogin() : String
  41. {
  42. return $this->login;
  43. }
  44. public function setHaslo($haslo) : void
  45. {
  46. $this->haslo = $haslo;
  47. }
  48. public function getHaslo() : String
  49. {
  50. return $this->haslo;
  51. }
  52. private $db;
  53. public function bazaDanych($db)
  54. {
  55. $this->db = $db;
  56. return $this->db;
  57. }
  58. public function rejestracja($login,$haslo)
  59. {
  60. $this->setLogin($login);
  61. $this->setHaslo($haslo);
  62. $login = $this->getLogin();
  63. $haslo = $this->getHaslo();
  64. $this->db->query(/*ZAPYTANIE INSERT*/);
  65. }
  66. }
  67.  
  68. $Uzytkownik = new Uzytkownik();
  69. $Uzytkownik->bazaDanych($Db->getConnection());
  70. $Uzytkownik->rejestracja('login','haslo');
  71.  

Napisany przez: viking 29.11.2019, 19:36:46

Podstawowe pytanie - po co ci ten singleton? Kod ogólnie dalej fatalny.

Napisany przez: huberthx 29.11.2019, 20:01:54

Pomijając ten singleton - co ogólnie znowu zepsułem ?

Napisany przez: nospor 30.11.2019, 09:57:42

np to

  1. $this->setLogin($login);
  2. $this->setHaslo($haslo);
  3. $login = $this->getLogin();
  4. $haslo = $this->getHaslo();
  5. $this->db->query(/*ZAPYTANIE INSERT*/);

Jaki tu sens w tym kodzie?
Na dzien dobry masz zmienne $login i haslo, potem te zmienne ustawiasz set.... a potem je pobierasz get... i w rezultacie masz to co miales
O te 4 linijki
  1. $this->setLogin($login);
  2. $this->setHaslo($haslo);
  3. $login = $this->getLogin();
  4. $haslo = $this->getHaslo();

Mozna wywalic bo nic nie wnosza do tej funkcji

Napisany przez: huberthx 30.11.2019, 10:58:42

Szczerze ja myślałem o tym żeby w metodach set była walidacja danych.
Przepraszam za to że nie podałem tego w kodzie - moje niedopatrzenie.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)