Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Tworzenie połączenia z bazą danych
Forum PHP.pl > Forum > PHP > Object-oriented programming
pitu
Mam pytanie, zaczynam dopiero z OOP. Stworzyłem klasę służącą do połączenia z bazą danych.

Klasa:
  1. <?php
  2. class Db{
  3. private $dbh;
  4.  
  5. public function __construct(){
  6. $host = 'localhost';
  7. $dbname = '';
  8. $user = '';
  9. $pass = '';
  10.  
  11. try{
  12. $this->dbh = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
  13. $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  14. }
  15. catch(PDOException $e){
  16. echo $e->getMessage();
  17. exit();
  18. }
  19. }
  20.  
  21. public function __destruct(){
  22. $this->dbh = null;
  23. }
  24. }
  25. ?>


W innej klasie mam:
  1. private $db;
  2.  
  3. public function __constructor(Db $db){
  4. $this->db = $db;
  5. }
  6. public function delArticle($id){
  7. $del = $this->db->exec('DELETE FROM artykuly WHERE id = '.$this->id);
  8. }


W pliku głównym:
  1. $db = new Db;
  2. $article = new Article($db);
  3. echo $article->delArticle(1);


Niestety otrzymuję błąd z informacą, że $db nie jest obiektem i nie mogę wywołać na jego rzecz metody exec()
  1. Call to a member function exec() on a non-object...
b4rt3kk
Czy ta inna klasa dziedziczy po Db? Jeśli tak to wystarczy tyle:

  1. public function delArticle($id){
  2. $del = $this->dbh->exec('DELETE FROM artykuly WHERE id = '.$this->id);
  3. }


i zmienić private $dbh; na protected?
pitu
Ok dzięki, mam jednak pytanie czy dało by się obejść bez dziedziczenia po klasie Db? Chciałem przekazać w parametrze obiekt klasy Db. Jest to tylko nauka OOP i myślę, że przy rozbudowie skryptu lepszym rozwiązaniem byłoby właśnie przekazanie obiektu Db niż ciągłe dziedziczenie.
b4rt3kk
Zmienna typu private jest dostępna tylko wewnątrz klasy, tak więc musisz dopisać funkcję która ją zwróci: __get().
pitu
Zailustruję jak ja myślę, chcąc przekazać obiekt Db jako parametr w innej klasie. Lecz to nie działa.

W pliku głównym tworzę egzemplarz obiektu Db oraz egzemplarz artykulu:
  1. $db = new Db;
  2.  
  3. $article = new Article($db);


W klasie Article mam:
  1. public function __constructor($db){
  2. $this->db = $db;
  3. }
  4. public function delArticle($id){
  5. $del = $this->db->exec('DELETE FROM artykuly WHERE id = '.$this->id);
  6. }


Czyli według mojego rozumowania w konstruktorze klasy Article przekazuję new Db które przypisane jest do właściwości $db. Czyli $db powinno być egzemplarzem klasy Db bez jej dziedziczenia. Niestety PHP wywala, że $db nie jest obiektem.
b4rt3kk
Bo klasa nie jest obiektem przecież, tylko klasą. smile.gif

  1.  
  2. public function __constructor(Db $db){
  3. $this->db = $db->wartoscDbh();
  4. }


Dopisz do klasy Db:

  1. public function wartoscDbh() {
  2. return $this->dbh;
  3. }


I tutaj argument funkcji jest zbędny, ponieważ operujesz na obiekcie, a nie na zmiennej, swoją drogą nigdzie nie przypisujesz wartości. Więc albo dodaj do konstruktora $this->id = costam, albo zmień w zapytaniu na $id.

  1. public function delArticle($id){
  2. $del = $this->db->exec('DELETE FROM artykuly WHERE id = '.$this->id);
  3. }
CuteOne
@UP klasa to obiekt pełną gębą wink.gif

@pitu

Wiesz w jakim celu używasz klasy Db a nie bezpośrednio PDO? Bo jeżeli ma ona służyć TYLKO połączeniu z bazą to taki kod jest całkowicie bez sensu i może być zastąpiony zwykłą funkcją...

  1. function connect(){
  2.  
  3. $host = 'localhost';
  4. $dbname = '';
  5. $user = '';
  6. $pass = '';
  7.  
  8. try{
  9. $dbh = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
  10. $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  11. }
  12. catch(PDOException $e){
  13. echo $e->getMessage();
  14. exit();
  15. }
  16.  
  17. return $dbh;
  18. }
  19.  
  20.  
  21. $db = connect();
  22.  
  23. $art = new Article($db);


Zobacz sobie do Zenda jak tam zaprojektowano obsługę bazy danych i wyciągnij wnioski
pamil
Cytat(CuteOne @ 7.10.2012, 00:49:07 ) *
@UP klasa to obiekt pełną gębą wink.gif

Klasa nie jest obiektem, obiekt to instancja klasy. Gdyby klasa była obiektem, każda klasa implementowałaby przymusowego Singletona.
lord2105
Proponuję wykorzystać Singletona, zastosować go w klasie DB i wykonywać w ten sposób:

  1. DB::getInstance()->exec('QUERY');
phpion
Cytat(pitu @ 4.10.2012, 01:58:07 ) *
W klasie Article mam:
  1. public function __constructor($db){
  2. $this->db = $db;
  3. }
  4. public function delArticle($id){
  5. $del = $this->db->exec('DELETE FROM artykuly WHERE id = '.$this->id);
  6. }


Czyli według mojego rozumowania w konstruktorze klasy Article przekazuję new Db które przypisane jest do właściwości $db. Czyli $db powinno być egzemplarzem klasy Db bez jej dziedziczenia. Niestety PHP wywala, że $db nie jest obiektem.

Nie __constructor tylko __construct. Po tej zmianie powinno śmigać.
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.