Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Problem z klasą mysql
Forum PHP.pl > Forum > PHP > Object-oriented programming
virtualman
Witam zacząłem pisać własną klase, ale mam błędy:
  1. ! ) Warning: mysql_query() expects parameter 2 to be resource, null given in C:\wamp\www\gra\class.php on line 47
  2. Call Stack
  3. # Time Memory Function Location
  4. 1 0.0006 670512 {main}( ) ..\index.php:0
  5. 2 0.0052 725288 user->add( ) ..\index.php:6
  6. 3 0.0054 726152 mysql->query( ) ..\class.php:97
  7. 4 0.0054 726200 mysql_query ( ) ..\class.php:47
  8.  
  9.  
  10. ( ! ) Warning: mysql_close() expects parameter 1 to be resource, null given in C:\wamp\www\gra\class.php on line 62
  11. Call Stack
  12. # Time Memory Function Location
  13. 1 0.0057 716504 mysql->__destruct( ) ..\class.php:0
  14. 2 0.0057 716552 mysql_close ( ) ..\cl

Kod PHP to:
  1. class mysql
  2. {
  3. private $host='localhost';
  4. private $name='root';
  5. private $pas='';
  6. private $db='game';
  7. private $handler;
  8.  
  9. public function connect(){
  10. $this->handler=mysql_connect($this->host,$this->name,$this->pas)
  11. or die('Błąd podczas łączenia z bazą danych.');
  12. mysql_select_db($this->db,$this->handler)
  13. or die('Błąd podczas łączenia z bazą danych.');
  14. }
  15.  
  16. public function set($host,$name,$pas,$db){
  17. $this->host = $host;
  18. $this->name = $name;
  19. $this->pas = $pas;
  20. $this->db = $db;
  21. }
  22.  
  23. public function query($query){
  24. $return=mysql_query($query,$this->handler);
  25. return $return;
  26. }
  27.  
  28. public function query_num($query){
  29. $result = mysq_query($query,$this->handler);
  30. return mysql_num_rows($result);
  31. }
  32.  
  33. public function query_fetch($query){
  34. $result = mysql_query($query,$this->handler);
  35. return mysql_fetch_array($result);
  36. }
  37.  
  38. public function __destruct(){
  39. mysql_close($this->handler);
  40. }
  41. }
  42.  
  43. class user extends mysql
  44. {
  45.  
  46. private $id;
  47.  
  48. public function setid($id){
  49. $this->id=$id;
  50. }
  51.  
  52. public function getid(){
  53. return $this->id;
  54. }
  55.  
  56. public function add($username,$password,$mail){
  57. $time=time();
  58. $data=date("d.m.Y");
  59. $code="";
  60. for($l=1; $l<=24; $l++){
  61. $a=rand(0,2);
  62. switch($a){
  63. case 0:
  64. $code .= chr(rand(30,39));
  65. break;
  66. case 1:
  67. $code .= chr(rand(65,90));
  68. break;
  69. case 2:
  70. $code .= chr(rand(97,122));
  71. break;
  72. }
  73. }
  74. $this->query("INSERT INTO user ('user','password','mail','date','last','activate') VALUES ('$username','$password','$mail','$data','$time',$code)");
  75. }
  76. }

Proszę o pomoc!
crocodillo
Po pierwsze w destruktorze powinieneś sprawdzać, czy jest zdefiniowana zmienna $handler np:
  1. public function __destruct(){
  2. if ($this->handler) mysql_close($this->handler);


Nie przyglądałem się dokładnie kodowi klasy, więc nie wiem czy są jakieś błędy, ale sprawdź w kodzie, czy wywołujesz funkcje set() i connect()
  1.  
  2. $u = new user();
  3. $u->set('abc','abc','abc','abc');
  4. $u->connect();


Jeśli łączysz się tylko z jedną bazą, to ja bym te funkcje (tzn set() i connect() )wrzucił do konstruktora klasy mysql.
tehaha
jeżeli piszesz sobie klasę w celach edukacyjnych to ok, ale w praktyce lepiej będzie jeśli będziesz używał PDO, a tak na marginesie to nie logicznie to zrobiłeś, np. w metodach query_num i query_fetch nie powinno być wysyłania zapytania bo wysłaniem zapytania zajmuje się metoda query(), po drugie lepiej jakbyś zmienne do łączenia przesyłał w konstruktorze a trzymał je w pliku konfiguracyjnym
virtualman
  1. class mysql
  2. {
  3. private $handler;
  4.  
  5. public function __construct($host='localhost',$name='root',$pas='',$db='game'){
  6. $this->host = $host;
  7. $this->name = $name;
  8. $this->pas = $pas;
  9. $this->db = $db;
  10. $this->handler=mysql_connect($host,$name,$pas)
  11. or die('Błąd podczas łączenia z bazą danych.');
  12. mysql_select_db($db,$this->handler)
  13. or die('Błąd podczas łączenia z bazą danych.');
  14. }
  15.  
  16. public function query($query){
  17. $return=mysql_query($query,$this->handler);
  18. return $return;
  19. }
  20.  
  21. public function query_num($query){
  22. $result = mysq_query($query,$this->handler);
  23. return mysql_num_rows($result);
  24. }
  25.  
  26. public function query_fetch($query){
  27. $result = mysql_query($query,$this->handler);
  28. return mysql_fetch_array($result);
  29. }
  30.  
  31. public function __destruct(){
  32. if($this->handler) mysql_close($this->handler);
  33. }
  34. }

Przerobiłem troszkę i dalej jest jeden błąd:
  1. Warning: mysql_close(): 4 is not a valid MySQL-Link resource in C:\wamp\www\gra\class.php on line 55
  2. Call Stack
  3. # Time Memory Function Location
  4. 1 0.0944 706072 mysql->__destruct( ) ..\class.php:0
  5. 2 0.0944 706120 mysql_close ( ) ..\class.php:55


żadnych pomysłów? ohmy.gif
crocodillo
O ile mi wiadomo to mysql_close() nie jest konieczne, gdyż połączenia są automatycznie zamykane na końcu skryptu. Być może to automatyczne zamknięcie następuje przed wywołaniem destruktora? Ale to tylko przypuszczenie, bo tak naprawdę to nie mam pojęcia w jakich kolejnościach co jest wywoływane.
virtualman
Ja też nie orientuje się w kolejności wykonywania, ale wiem, że jak przeglądałem inną klase to było mysql_connect w destruktorze... Jakie mogą być skutki "uboczne" nie użycia funkcji mysql_connect()
?
crocodillo
Takie, że zasoby zostaną zwolnione dopiero po zakończeniu wykonywania się skryptu. PHP używam od kilku lat, co prawda nigdy nie pisałem nic tak wielkiego, że trzeba było bardzo dbać o pamięć, ale nigdy nie używałem mysql_close(). O ile się nie mylę to na php.net też chyba jest napisane, że używanie tej funkcji nie jest konieczne. Oczywiście to jest tylko moje zdanie, być może inni uważają inaczej.
virtualman
czyli jeśli nie korzystam z kilku baz danych na raz to nie muszę tego używać? to w sumie chyba sobie odpuszczę, choć wolałbym wiedzieć co nie tak, bo lepiej rozwiązać problem niż pominąć funkcję...
greycoffey
Czy klasa "user" rozszerza klasę "mysql"? Nie, ona ją wykorzystuję. Poczytaj o różnicy między kompozycją a dziedziczeniem.
Natomiast co do błędu, sprawdziłbym czy resource jest zwracany z mysql_connecta.
Masz włączone E_NOTICE? Moim pomysłem jest to, że dziedziczysz klasę mysql na user, w związku z czym wywołujesz zmienną PRYWATNĄ $this->handler.
Tymczasowym uleczeniem tego będzie zmienienie modyfikatora $this->handler na protected. To tylko zaślepka, ponieważ kod jest do przepisania wink.gif
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.