Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php] błąd w klasie
Forum PHP.pl > Forum > PHP
Lejto
Mam taki fragment index.php
  1. include("config.php");
  2. include("libs/db.class.php");
  3. $db = new DB();
  4. include("libs/core.class.php");
  5. $c = new core($db);
  6. include("function.inc.php");
  7. $f = new functions();

wszystko chodzi
wchodzę na stronę gdzie rejestruje usera
połączenie z bazą jest wywołuje funkcje sprawdzającą
  1. global $db;
  2. global $page;
  3. global $f;
  4.  
  5. include("libs/user.class.php");
  6. $u = new User($db);
  7.  
  8. $user = $u->getByUsername($_POST['username']);

połączenie z bazą w tym pliku jest ale nie ma już jego w klasie user.class.php jak juz wcześniej wymieniłem plik code.class.php (tam wszystko działa)
user.class.php
  1. class User
  2. {
  3. public $uid;
  4. public $fields = array();
  5.  
  6. public function __construct($sql)
  7. {
  8. $this->sql = $sql;
  9. $this->uid = null;
  10. $this->fields = array('username' => '',
  11. 'password' => '',
  12. 'emailAddr' => '',
  13. 'isActive' => false);
  14. }
  15. public static function getByUsername($username)
  16. {
  17. echo 'aa';
  18. $db = $this->sql;
  19. echo 'aa';
  20. $sql = $db->query('select * from users where username = $username');
  21.  
  22. }

db.class.php
  1. class DB{
  2.  
  3. public $_lacz;
  4.  
  5. public function __construct()
  6. {
  7. $this->_lacz = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
  8. if(mysqli_connect_errno() != 0)
  9. {
  10. echo '<p>Wystąpił błąd połączenia: ' . mysqli_connect_error(). ', przepraszamy.';
  11. }
  12. }

dlaczego nie mam połączenie w klasie user?
reszta klas działa normalnie
darko
Gdzie masz pole $sql w klasie User ?
Lejto
jak pole $sql?
w core.class mam
  1. class core{
  2.  
  3. public function __construct($sql)
  4. {
  5. $this->sql = $sql;
  6. }
  7. ////////////
  8. }

i jest ok
darko
Nie zauważyłem że public static function getByUsername($username) Ok w takim razie - wiesz, że w metodach statycznych nie korzysta się z $this, a z self:: ? Poza tym źle wywołujesz tę metodę, powinno być: $u::getByUsername($_POST['username']);
skowron-line
  1. public [url="http://www.php.net/static"]static[/url] function getByUsername($username)

usuń static.
darko
Jak usuniesz static, to dodaj jeszcze w klasie User pole
protected $sql;
Lejto
usunąłem ale nadal nie chce wykonać zapytania var_dump($db); zwraca NULL
darko
a dodałeś to pole protected $sql; ?
Lejto
jakie protected?
mam normalną prywatność dla tego jak w innych klasach

ok już wiem o co chodzi smile.gif
dodałem i poprawnie wykonuję te funkcje ale teraz zatrzymuje się na wywołaniu $user->userId
  1. $user = $u->getByUsername($_POST['username']);
  2. if ($user->userId)
  3. {
  4. echo '<p><strong>Przepraszamy, ' .
  5. 'takie konto już istnieje.</strong></p> <p>Prosimy podać ' .
  6. 'inną nazwę użytkownika.</p>';
  7.  
  8. }

klasa (część)
  1. <?
  2. class User
  3. {
  4. public $uid;
  5. public $fields = array();
  6. protected $sql;
  7.  
  8. public function __construct($sql)
  9. {
  10. $this->sql = $sql;
  11. $this->uid = null;
  12. $this->fields = array('username' => '',
  13. 'password' => '',
  14. 'emailAddr' => '',
  15. 'isActive' => false);
  16. }
  17. public function __get($field)
  18. {
  19. if($field == 'userId')
  20. {
  21. return $this->uid;
  22. }
  23. else
  24. {
  25. return $this->fields[$field];
  26. }
  27. }
  28. public function __set($field, $value)
  29. {
  30. if(array_key_exists($field, $this->fields))
  31. {
  32. $this->fields[$field] = $value;
  33. }
  34. }
  35. public static function validateUserName($username)
  36. {
  37. return preg_match('/^[A-Z0-9]{2.20}$/i', $username);
  38.  
  39. }
  40. public static function validateEmailAddr($email)
  41. {
  42. return filter_var($email, FILTER_VALIDATE_EMAIL);
  43. }
  44. public static function getById($uid)
  45. {
  46. $db = $this->sql;
  47. $u = new User($db);
  48. $sql = $db->query('select username, password, email_addr, is_active from users where userid = $uid');
  49.  
  50. if($sql->num_rows)
  51. {
  52. $row = $sql->fetch_array();
  53. $u->username = $row['username'];
  54. $u->password = $row['password'];
  55. $u->emailAddr = $row['email_addr'];
  56. $u->isActive = $row['is_active'];
  57. $u->uid = $uid;
  58. }
  59. return $u;
  60. }
  61.  
  62. public function getByUsername($username)
  63. {
  64. $db = $this->sql;
  65. $sql = $db->query('select * from users where username = $username');
  66. }
  67.  
  68.  
  69.  
  70. }
  71. ?>
darko
Metoda getByUsername nie operuje na polu userId
Lejto
ale mam to w __get
no to jest mam to poprawić?
darko
Wypełnij pola klasy User analogicznie, jak w metodzie getById tylko nie statycznie, a kontekstowo z użyciem wskaźnika $this. W metodzie getByUsername wyciągasz dane z bazy, ale nigdzie ich nie przypisujesz do pól klasy User, chodzi o to, że powinieneś nadpisać wartości pól zapisane po wywołaniu konstruktora.
Lejto
nie za bardzo cię rozumiem, poprawiłem klase, rejestruje ale nie sprawdza czy nazwa użytkownika się powtarza ;/
  1. <?
  2. class User extends functions
  3. {
  4. public $uid;
  5. public $fields = array();
  6. protected $sql;
  7.  
  8. public function __construct($sql)
  9. {
  10. $this->sql = $sql;
  11. $this->uid = null;
  12. $this->fields = array('username' => '',
  13. 'password' => '',
  14. 'emailAddr' => '',
  15. 'isActive' => false);
  16. }
  17. public function __get($field)
  18. {
  19. if($field == 'userId')
  20. {
  21. return $this->uid;
  22. }
  23. else
  24. {
  25. return $this->fields[$field];
  26. }
  27. }
  28. public function __set($field, $value)
  29. {
  30. if(array_key_exists($field, $this->fields))
  31. {
  32. $this->fields[$field] = $value;
  33. }
  34. }
  35. public function validateUserName($username)
  36. {
  37. if(strlen($username)<3)
  38. {
  39. echo 'Nazwa użytkownika musi zawierać co najmniej 3 znaki';
  40. }
  41. else
  42. {
  43. return true;
  44. }
  45. if(strlen($username)>20)
  46. {
  47. echo 'Za długa nazwa użytkownika max 20 znaków';
  48. }
  49. else
  50. {
  51. return true;
  52. }
  53. }
  54. public static function validateEmailAddr($email)
  55. {
  56. return filter_var($email, FILTER_VALIDATE_EMAIL);
  57. }
  58. public function getById($uid)
  59. {
  60. $db = $this->sql;
  61. $u = new User($db);
  62. $sql = $db->query('select username, password, email_addr, is_active from users where userid = $uid');
  63.  
  64. if($sql->num_rows)
  65. {
  66. $row = $sql->fetch_array();
  67. $u->username = $row['username'];
  68. $u->password = $row['password'];
  69. $u->emailAddr = $row['email_addr'];
  70. $u->isActive = $row['is_active'];
  71. $u->uid = $uid;
  72. }
  73. return $u;
  74. }
  75.  
  76. public function getByUsername($username)
  77. {
  78. $db = $this->sql;
  79. $u = new User($db);
  80.  
  81. $sql = $db->query('select user_id, password, email_addr, is_active from USERS where username = $username');
  82.  
  83. if($sql->num_rows)
  84. {
  85. $row = $sql->fetch_array();
  86. echo $row['username'];
  87. echo 'aa';
  88. $u->password = $row['password'];
  89. $u->emailAddr = $row['email_addr'];
  90. $u->isActive = $row['is_active'];
  91. $u->uid = $row['user_id'];
  92. }
  93. return $u;
  94. }
  95.  
  96. public function save()
  97. {
  98.  
  99.  
  100. $db = $this->sql;
  101. if($this->uid)
  102. {
  103. $sql = $db->query('update USERS set username = $this->username, password = $this->password,
  104. email_addr = $this->emailAddr, is_active = $this->isActive where user_id = $this->userId');
  105. }
  106. else
  107. {
  108. $sql = $db->query('insert into users (username, password, email_addr, is_active)
  109. values ("'.$this->username.'", "'.$this->password.'", "'.$this->emailAddr.'", "'.$this->isActive.'")');
  110. if(!$sql)
  111. {
  112. var_dump($this->password);
  113. }
  114. }
  115. }
  116.  
  117. public function setInactive()
  118. {
  119. $db = $this->sql;
  120. $this->isActive = false;
  121. $this->save();
  122.  
  123. $token = $this->random_text(5);
  124. $sql = $db->query('insert into users_pending (user_id, token) values ($this->uid, $token)');
  125.  
  126. return $token;
  127. }
  128.  
  129. public function setActive($token)
  130. {
  131. $db = $this->sql;
  132.  
  133. $sql = $db->query('select token from users_pending where user_id = $this->uid and token = $token');
  134.  
  135. if(!$sql->num_rows)
  136. {
  137. return false;
  138. }
  139. else
  140. {
  141. $sql = $db->query('delete from users_pending where user_id = $this->uid and token = $this->token');
  142. $this->isAdcive = true;
  143. $this->save();
  144. return true;
  145. }
  146. }
  147. }
  148. ?>
Crozin
To może najpierw kilka uwag:

#2: Klasa 'User' dziedziczy po 'functions' (może jakaś konsekwencja w nazewnictwie?) co wydaje mi się nieco dziwne. W jaki sposób użytkownik jest rozszerzeniem funkjci?
#4,5: Dlaczego te pola są publiczne? Przecież z tego co widzę stworzyłeś dla nich magiczne gettery/settery.
#6: SQL to skrót odnoszący się do języka zapytań, a z tego co widzę to używasz tego jako referencji do czegoś co pełni rolę API do komunikacji z bazą... niepotrzebne nieporozumienia się rodzą w takiej sytuacji
#11,12: Dlaczego nie ustawisz sobie wartości domyślnych odrazu w momencie deklarowania składowych klasy?
#35: Jak do tej pory ta klasa wygląda na taką, która ma reprezentować użytkownika... a tu nagle wyskakuje jakaś metoda do walidacji nazwy użytkownika. Powinieneś wydzielić te (i podobne) metody do innego obiektu będącego walidatorem dla użytkownika używanym podczas rejestracji. Poza tym kod tej metody jest bez sensu... najpierw sprawdzasz czy długość nazwy jest mniejsza od 3-ech. Jeśli tak to wyświetlasz komunikat (co już jest błędem, bo obiekt niepotrzebnie bierze na swoje barki dodatkową kwestię jaką jest prezentowanie treści użytkownikowi). Jeżeli nazwa jest dłuższa lub równa podanym 3-em znakom to metoda kończy działanie zwracając TRUE. To po jakie licho jest jeszcze później ten drugi warunek? Przecież jeżeli nazwa jest krótsza od tych 3-ech znaków to już nie będzie dłuższa niż 20, a sytuacja gdy nazwa jest dłuższa niż 2 znaki po czym następuje sprawdzenie czy aby przypadkiem nie jest dłuższa niż 20 znaków nie może nigdy zajść...
#58: Tutaj znów obiekt reprezentujący użytkownika pełni rolę kolekcji użytkowników... pobieranie użytkowników wydziel do osobnego obiektu odpowiedzialnego za to konkretne zadanie (tj. reprezentację kolekcji i operacji na niej)
#60: W jakim celu każdorazowo robisz: $db = $this->sql? Po co ta dodatkowa referencja?
#76: Zauważyłeś, że ta metoda robi dokładnie to co wcześniejsza tylko różni się drobnym fragmentem wykorzystywanego zapytania? Google: DRY. Innymi słowy: wydziel sobie jakąś prywatną metodę pobierającą użytkowników i z poziomu getById, getByUsername zwracaj jej wynik (jako argument przekazując coś w stylu:
"id = 3" lub "username = 'abc'"
#103: Nie widzę żadnej filtracji danych przed wprowadzeniem ich do treści zapytania. Co więcej te zapytania nie mają prawa działać - w ich treści masz:
...username = abc my username...
Przeczytaj w dokumentacji jak w MySQL (bo chyba z tego korzystasz) reprezentuje się tekst - podobnie jak w kodzie PHP podpowiem.
#124: Poczytaj o różnicy pomiędzy: "blah blah $variable blah blah", a 'blah blah $variable blah blah'

Cytat
rejestruje ale nie sprawdza czy nazwa użytkownika się powtarza

1) Nie pokazujesz jak używasz obiektu tej klasy
2) Nie widzę też w tym kodzie niczego co by mogło sprawdzać unkalność nazwy użytkownika...
Lejto
dziedziczę jeszcze jeszcze functions bo jest tam funkcja którą potrzebuję do wylosowania tekstu
#4,5 ok zmienię
#6 mógłbyś wyjaśnić?
#11,12 to też smile.gif (ucze się cały czas oop) nie wiem jeszcze wszystkiego...
#35 i #58 to jak bym miał to poprawić?
#60 no właśnie o tym już kiedyś pisałem potrzebuje tego aby było połączenie, przyjrzyj się klasie łączącej
#124 jakieś namiary? nie wiem za bardzo o co chodzi

dzięki za wskazówki
Crozin
Cytat
dziedziczę jeszcze jeszcze functions bo jest tam funkcja którą potrzebuję do wylosowania tekstu
Nie o to chodzi w dziedziczeniu. Jest sporo materiałów dotyczących obiektówki - traktujących o teorii - poczytaj jeszcze zanim zabierzesz się za pisanie.
Cytat
#6 mógłbyś wyjaśnić?
Po prostu zwróciłem uwagę na to, że źle sobie nazywasz zmienne. Pod $sql umieszczasz sobie obiekt, który z SQLem nie ma wiele wspólnego. Po prostu: zła praktyka wg mnie.
Cytat
11,12 to też (ucze się cały czas oop) nie wiem jeszcze wszystkiego...
Zastanawiałem się dlaczego nie zrobisz po prostu:
  1. <?php
  2.  
  3. class ABC {
  4. protected $xyz = array('...' => '...', '...' => '...');
  5.  
  6. //...
  7. }
Cytat
#35 i #58 to jak bym miał to poprawić?
Utworzyć kilka nowych klas, gdzie każda odpowiedzialna jest za jedną konkretną rzecz i doprowadzić do współpracy różnych obiektów tych klas między sobą, a nie tak jak teraz masz... jeden obiekt robiący wszystko co się tylko da - ma on za duży zakres obowiązków.
Cytat
#60 no właśnie o tym już kiedyś pisałem potrzebuje tego aby było połączenie, przyjrzyj się klasie łączącej
Eee... ale Ty po prostu robisz niepotrzebnie kolejną referencję do tego obiektu... Zaśmiecasz kod tylko niepotrzebnymi zmiennymi, nie zyskując nic na tym, bo zarówno $db->doSth('...'); jak i $this->db->doSth('...') są bardzo czytelne.
Cytat
#124 jakieś namiary? nie wiem za bardzo o co chodzi
Oczywiście manual PHP, rozdział dotyczący typu danych: String (nie pomyl z listą funkcji operujących na tekscie). Ale jeżeli nie masz tak elementarnej wiedzy z zakresu działania PHP (różnica pomiędzy "test", a 'test') to nie wiem czy dobrym pomysłem jest branie się za prog. obiektowe.
Lejto
ok dzięki smile.gif
ale powiedź jeszcze dlaczego nie chce mi działać wywołanie $user->userId
  1.  
  2. $user = $u->getByUsername($_POST['username']);
  3. if ($user->userId)
  4.  
  5. {
  6.  
  7. echo '<p><strong>Przepraszamy, ' .
  8.  
  9. 'takie konto już istnieje.</strong></p> <p>Prosimy podać ' .
  10.  
  11. 'inną nazwę użytkownika.</p>';
  12.  
  13. }


poradzi ktoś coś?
kod już cały potrzebny chyba podałem.
Crozin
Wyświetl sobie błędy zapytań MySQL...
Lejto
nie wpadł bym na to smile.gif
problem rozwiązany, błąd był w zapytaniu (myślałem że gdzieś funkcje źle zrobione)
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.