Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

3 Stron V   1 2 3 >  
Reply to this topicStart new topic
> moja klasa z zapytaniami SQL
damianooo
post
Post #1





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Witam,

Proszę o sprawdzenie czy zapis mojej klasy z zapytaniami SQL jest poprawny pod względem OOP, co można by zmienić, uproscić itd. Potrzebuję takiej klasy aby zrobić sobie podstawowe zapytania CRUD dla obsługi jednej tabeli bazy danych. Dobrze się do tego zabralem ?

  1. class MyQueries extends PDO
  2. {
  3.  
  4. public function __construct()
  5. {
  6. parent::__construct('mysql:host=localhost;dbname=mydatabase', 'login', 'password');
  7. }
  8.  
  9. public static function getCities()
  10. {
  11. try {
  12. $conn = new MyQueries();
  13. $stmt = $conn->prepare('SELECT * FROM city');
  14. $stmt->execute();
  15. } catch (PDOException $e) {
  16. echo 'ERROR: ' . $e->getMessage();
  17. }
  18.  
  19. return $stmt;
  20. }
  21.  
  22. public static function create(){
  23. // code
  24. }
  25.  
  26. public static function delete($id){
  27. // code
  28. }
  29.  
  30. }



dzięki

Ten post edytował damianooo 26.06.2013, 18:11:58
Go to the top of the page
+Quote Post
Spawnm
post
Post #2





Grupa: Moderatorzy
Postów: 4 069
Pomógł: 497
Dołączył: 11.05.2007
Skąd: Warszawa




Źle. Wydziel model odpowiedzialny za łączenie z bazą. Wywal static. Obecnie jest to zbiór funkcji zamkniętych w klasie. Nie ma to nic wspólnego z oop.

Go to the top of the page
+Quote Post
damianooo
post
Post #3





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Czy tak będzie lepiej ? ... nie wiem jak z tym rozdzieleniem połączenia z bazą danych. Można prosić o podpowiedź. Bo teraz w tej postaci to mi nie działa.

Teraz mam tak:

  1. class DBObject extends PDO
  2. {
  3.  
  4. public function __construct()
  5. {
  6. parent::__construct('mysql:host=localhost;dbname=database', 'login', 'password');
  7. }
  8.  
  9. }



  1. class City extends DBObject
  2. {
  3. public $name;
  4. protected $country;
  5.  
  6. public function __construct($name, $country)
  7. {
  8. $this->setName($name);
  9. $this->setCountry($country);
  10. }
  11.  
  12. public function setName($name)
  13. {
  14. $this->name = $name;
  15. return $this;
  16. }
  17.  
  18. public function getName()
  19. {
  20. return $this->name;
  21. }
  22.  
  23. public function setCountry(Country $country)
  24. {
  25. $this->country = $country;
  26. return $this;
  27. }
  28.  
  29. public function getCountry()
  30. {
  31. return $this->country;
  32. }
  33.  
  34. public function save()
  35. {
  36. $stmt = $this->prepare('INSERT INTO city VALUES(:name,:country_id)');
  37. $stmt->execute(array(':name' => $this->name, ':country_id' => $this->country_id));
  38. }
  39.  
  40. public function load()
  41. {
  42. $stmt = $this->prepare('SELECT c.city_id,c.name,cn.name as country FROM city c INNER JOIN country cn ON c.country_id = cn.country_id');
  43. $stmt->execute();
  44. }
  45.  
  46. }




Bardzo proszę o znaleznienie błędów i poprawienie mnie.
Dzięki

Ten post edytował damianooo 27.06.2013, 22:16:43
Go to the top of the page
+Quote Post
sajegib
post
Post #4





Grupa: Zarejestrowani
Postów: 352
Pomógł: 59
Dołączył: 16.01.2013

Ostrzeżenie: (0%)
-----


zrób nową klasę od łączenia z bazą danych i przekaż jej obiekt jako parametr do konstruktora np:

  1. $db = new database(new connection());
Go to the top of the page
+Quote Post
damianooo
post
Post #5





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


czy tak? :
  1. class DBObject extends PDO
  2. {
  3. public function __construct()
  4. {
  5. parent::__construct('mysql:host=localhost;dbname=database', 'login', 'password');
  6. }
  7. }




i wtedy tak:


  1. class City extends DBObject
  2. {
  3. public $name;
  4. protected $country;
  5. public $db;
  6.  
  7. public function __construct($name, $country)
  8. {
  9. $this->db = new DBObject();
  10. $this->setName($name);
  11. $this->setCountry($country);
  12. }
  13.  
  14. public function setName($name)
  15. {
  16. $this->name = $name;
  17. return $this;
  18. }
  19.  
  20. public function getName()
  21. {
  22. return $this->name;
  23. }
  24.  
  25. public function setCountry(Country $country)
  26. {
  27. $this->country = $country;
  28. return $this;
  29. }
  30.  
  31. public function getCountry()
  32. {
  33. return $this->country;
  34. }
  35.  
  36. public function save()
  37. {
  38. $stmt = $this->db->prepare('INSERT INTO city VALUES(:name,:country_id)');
  39. $stmt->execute(array(':name' => $this->name, ':country_id' => $this->country_id));
  40. }
  41.  
  42. public function load()
  43. {
  44. $stmt = $this->d->prepare('SELECT c.city_id,c.name,cn.name as country FROM city c INNER JOIN country cn ON c.country_id = cn.country_id');
  45. $stmt->execute();
  46. }
  47.  
  48. public function update()
  49. {
  50. // code here
  51. }
  52.  
  53. public function delete()
  54. {
  55. // code here
  56. }
  57.  
  58. }


Ten post edytował damianooo 27.06.2013, 22:31:30
Go to the top of the page
+Quote Post
Spawnm
post
Post #6





Grupa: Moderatorzy
Postów: 4 069
Pomógł: 497
Dołączył: 11.05.2007
Skąd: Warszawa




W twoim przypadku jeśli klasa dziedzicząca PDO nie robi nic, żadnego query buildera itd. to można by ją sobie darować.
Do konstruktora przekazuj $pdo i tyle. Poczytaj też o dziedziczeniu, kiedy się je stosuje i po co. Bo klasa City nie powinna dziedziczyć klasy do db (IMG:style_emoticons/default/wink.gif)
Go to the top of the page
+Quote Post
damianooo
post
Post #7





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


zrobiłem tak ale nie wiem czemu nie zapisuje mi rekordu do bazy danych. Co mogę jeszcze mieć źle ?

  1. class City
  2. {
  3. public $name;
  4. public $db;
  5.  
  6. public function __construct($name)
  7. {
  8. $this->db = new PDO('mysql:host=localhost;dbname=database', 'login', 'password');
  9. $this->setName($name);
  10. }
  11.  
  12. public function setName($name)
  13. {
  14. $this->name = $name;
  15. return $this;
  16. }
  17.  
  18. public function save()
  19. {
  20. $stmt = $this->db->prepare('INSERT INTO city VALUES(:name,:country_id)');
  21. $stmt->execute(array(':name' => $this->name, ':country_id' => 1));
  22. }
  23.  
  24. }



i wywołanie w innym pliku:

  1. require_once 'Model/City.php';
  2. $city = new City('Madrid');
  3. $city->save();


Ten post edytował damianooo 28.06.2013, 08:24:15
Go to the top of the page
+Quote Post
Spawnm
post
Post #8





Grupa: Moderatorzy
Postów: 4 069
Pomógł: 497
Dołączył: 11.05.2007
Skąd: Warszawa




Nie. Czemu city zajmuje się łączeniem z pdo? Inne modele też będą to robić?
  1. $pdo = new PDO(...);
  2. $city = new City($pdo);
  3. $city->setName('lol')
  4. ->setCountry('lol2')
  5. ->add();

I nie używaj nazwy save() do insertowania, w frameworkach ta nazwa oznacza update rekordu jeśli istnieje, lub instert jeśli nie istnieje.
Go to the top of the page
+Quote Post
damianooo
post
Post #9





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Zrobiłem tak , ale nadal coś nie tak z tym moim połączeniem, nadal w bazie po odświeżeniu strony nie ma żadnej zmiany, coś nadal robię źle ... ehh .

  1. class City
  2. {
  3. public $name;
  4. public $db;
  5.  
  6. public function __construct(PDO $pdo)
  7. {
  8. $this->db = $pdo;
  9. }
  10.  
  11. public function setName($name)
  12. {
  13. $this->name = $name;
  14. return $this;
  15. }
  16.  
  17. public function add()
  18. {
  19. $stmt = $this->db->prepare('INSERT INTO city VALUES(:name,:country_id)');
  20. $stmt->execute(array(':name' => $this->name, ':country_id' => 1));
  21. }
  22.  
  23. }


i wywołanie:

  1. require_once 'Model/City.php';
  2.  
  3. $pdo = new PDO('mysql:host=localhost;dbname=database', 'login', 'password');
  4. $city = new City($pdo);
  5. $city->add();


Ten post edytował damianooo 28.06.2013, 08:35:29
Go to the top of the page
+Quote Post
nospor
post
Post #10





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




No to wyswietl blad PDO a bedziesz wiedzial co jest nie tak :/

ps: nie masz juz przypadkiem miasta o ID = 1?
Go to the top of the page
+Quote Post
Spawnm
post
Post #11





Grupa: Moderatorzy
Postów: 4 069
Pomógł: 497
Dołączył: 11.05.2007
Skąd: Warszawa




W wywołaniu zapomniałeś o ustawieniu name.

Daj private lub protected:
  1. public $name;
  2. public $db

http://pl.wikipedia.org/wiki/Hermetyzacja_%28informatyka%29
Go to the top of the page
+Quote Post
damianooo
post
Post #12





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


ehh faktycznie (IMG:style_emoticons/default/smile.gif) ... jednak nadal nie działa ... postanowiłem wyświetlić co PDO pluje i tak:

Mam tak:

  1. class City
  2. {
  3. private $name;
  4. private $db;
  5.  
  6. public function __construct(PDO $pdo)
  7. {
  8. $this->db = $pdo;
  9. }
  10.  
  11. public function setName($name)
  12. {
  13. $this->name = $name;
  14. return $this;
  15. }
  16.  
  17. public function add()
  18. {
  19. $stmt = $this->db->prepare('INSERT INTO city VALUES(:name,:country_id)');
  20. $stmt->execute(array(':name' => $this->name, ':country_id' => 1));
  21. }
  22.  
  23. }


i wywołanie:

  1. require_once 'Model/City.php';
  2.  
  3. $pdo = new PDO('mysql:host=localhost;dbname=database', 'login', 'password');
  4. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  5.  
  6. try {
  7. $city = new City($pdo);
  8. $city->setName('Katowice');
  9. $city->add();
  10. } catch (PDOException $e) {
  11. print_r($e->getTrace());
  12. }


a PDO krzyczy to:

Array ( [0] => Array ( [file] => /var/www/test/Model/City.php [line] => 43 [function] => execute [class] => PDOStatement [type] => -> [args] => Array ( [0] => Array ( [:name] => Katowice [:country_id] => 1 ) ) ) [1] => Array ( [file] => /var/www/test/test.php [line] => 12 [function] => add [class] => City [type] => -> [args] => Array ( ) ) )

Ten post edytował damianooo 28.06.2013, 08:45:58
Go to the top of the page
+Quote Post
nospor
post
Post #13





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




rety..... ty nie wyswietlaj sciezki bledu, tylko wyswietlaj blad....
Go to the top of the page
+Quote Post
damianooo
post
Post #14





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


a no tak , sorry (IMG:style_emoticons/default/smile.gif)


  1. SQLSTATE[21S01]: Insert value list does not match column list: 1136 Column count doesn't match value count at row 1
Go to the top of the page
+Quote Post
nospor
post
Post #15





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




No to chyba masz juz teraz napisane.... liczba kolumn jakie wstawiasz do tabeli jest mniejsza od wymaganej liczby kolumn jakie ustawiles dla tej tabeli
Go to the top of the page
+Quote Post
damianooo
post
Post #16





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


OK, mam , miało być tak:

  1. public function add()
  2. {
  3. $stmt = $this->db->prepare('INSERT INTO city (name,country_id) VALUES(:name,:country_id)');
  4. $stmt->execute(array(':name' => $this->name, ':country_id' => 1));
  5. }









Jeszcze chciałem prosić o podpowiedź jak pobrać ID zapisanego obiektu w bazie i przekazać go jako parametr przy zapisywaniu pola innego obiektu w sytuacji gdy encje połączone są w relacji "jeden do wielu" .

i potrzebuję zapisać to coś w ten deseń (country będzie pobierane na stronie z pola rozwijanego):

W klasie "Country" mam tak:

  1. public function findById($id)
  2. {
  3. $stmt = $this->db->prepare('SELECT * FROM Country WHERE country_id :id');
  4. $stmt->execute(array('id' => $id));
  5. $row = $stmt->fetch();
  6. return $row;
  7. }


i zapisuję to tak:

  1. require_once 'Model/Country.php';
  2. require_once 'Model/City.php';
  3.  
  4. $pdo = new PDO('mysql:host=localhost;dbname=database', 'login', 'password');
  5. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  6.  
  7. try {
  8. $country = new Country($pdo);
  9. $country->findById(2);
  10. $city = new City($pdo);
  11. $city->setName('Liverpool');
  12. $city->setCountry($country);
  13. $city->add();
  14. } catch (PDOException $e) {
  15. print_r($e->getMessage());
  16. }


PDO krzyczy:

  1. SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''2'' at line 1


Ten post edytował damianooo 28.06.2013, 11:15:18
Go to the top of the page
+Quote Post
nospor
post
Post #17





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




findById ci zwraca rekord, ale ty go w ogole nie przechwytujesz nigdzie
Go to the top of the page
+Quote Post
damianooo
post
Post #18





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


nie przychwytuję tzn. ?

zmieniłem tak:

  1. $country = new Country($pdo);
  2. $countryObject = $country->findById(2);
  3. $city = new City($pdo);
  4. $city->setName('Liverpool');
  5. $city->setCountry($countryObject);
  6. $city->add();


ale nadal źle
Go to the top of the page
+Quote Post
nospor
post
Post #19





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




$countryObject = $country->findById(2);
var_dump($countryObject);

No juz tak banalna analize to moglbys robic sam.... :/

poza tym pokaz jak wyglda teraz kod metody ADD

poza tym, skoro city potrzebuje ID. a ty ID przeciez masz, to po grzyba bawisz sie w budowanie obiektu. Chyba ze twoim celem jest sprawdzenie czy ten obiekt istnieje, w co akurat watpie (bez urazy)
Go to the top of the page
+Quote Post
damianooo
post
Post #20





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


obiekt nie istnieje masz rację, zrobiłem tak:

  1. $country = new Country($pdo);
  2. $countryObject = $country->findById(2);
  3. var_dump($countryObject);


i mam pusty ekran. Poza tym z obsługą wyjątków krzyczał mi:

  1. SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''2'' at line 1


metoda add City to:

  1. public function add()
  2. {
  3. $stmt = $this->db->prepare('INSERT INTO city (name,country_id)VALUES(:name,:country_id)');
  4. $stmt->execute(array(':name' => $this->name, ':country_id' => $this->country));
  5. }


Ten post edytował damianooo 28.06.2013, 11:48:49
Go to the top of the page
+Quote Post

3 Stron V   1 2 3 >
Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 26.08.2025 - 12:06