Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wzorzec Singletona w MySQL z PEAR
Forum PHP.pl > Forum > PHP > Object-oriented programming
Marys91
Witam,
chciałbym wykorzystać wzorzec Singletona do połączenia się z bazą danych (MySQL) i do tego dołożyłem sobie PEAR' a, ale coś mi nie idzie. To co mam to są takie pliki:

classa.Databases.php
  1. <?php
  2. require_once('pear/MDB2.php');
  3. require_once('config.php');
  4.  
  5.  
  6. class Datebase{
  7. private $conn;
  8.  
  9. private function __construct($zmienna=null){
  10. global $mysql_dsn;
  11.  
  12. if($zmienna==null){
  13. $zmienna = $mysql_dsn;
  14. }
  15.  
  16. $this->conn=MDB2::connect($zmienna);
  17. }
  18.  
  19. static public function instance(){
  20. static $objMDB2;
  21.  
  22. if (!isset($objMDB2)){
  23. $objMDB2 = new Datebase();
  24. }
  25.  
  26. return $objMDB2;
  27. }
  28.  
  29. function select($sql){
  30. $result = $this->conn->query($sql);
  31.  
  32. return $result;
  33. }
  34.  
  35. function fetchAll($sql){
  36. $result = $this->conn->fetchAll($sql);
  37.  
  38. return $result;
  39. }
  40.  
  41. }
  42. ?>


Wiem, że brakuje obsługi błędów.

test.php
  1. <?php
  2. require_once('class.Database.php');
  3.  
  4. $ble = Datebase::instance();
  5. $elb = $ble->fetchAll('SELECT * FROM moajtabela');
  6.  
  7. echo $elb;
  8. ?>


I teraz tak. Po pierwsze czy dobrze myślę o wzorze Singletona (dobrze jest napisana klasa)? Po drugie czemu mi wywala błąd(Fatal error: Call to undefined function: MDB2_Driver_mysqli::numCol(). in pear/MDB2.php on line 1950)? To wygląda na błąd PEAR, ale jak robię normalnie bez mojej klasy to jest dobrze. Po trzecie, widziałem gdzieś jak koleś właśnie tworzył takie metody jak u mnie (fetchAll), ale czy przed tym nie powinno występować query()?

Nie wiem co tu jeszcze może być źle
Noidea
PEAR MDB2 ma już wbudowany singleton http://pear.php.net/manual/en/package.data...tro-connect.php więc twoja klasa jest trochę bez sensu.

Twój singleton napisany jest w sumie dobrze. Nie zabezpiecza jedynie przed:
  1. <?php
  2.  
  3. $ble = Datebase::instance();
  4. $ble2 = clone $ble;
  5.  
  6. ?>


Dodaj do swojej klasy pustą funkcję:
private function __clone() {}


No i źle używasz fetchAll(). W tej bibliotece MDB2_Driver_Common::query() zwraca obiekt klasy MDB2_Result_Common, na którym dopiero można wykonać fetchAll().
Marys91
Czyli teraz trochę bez sensu jakby tworzyć tą klasę, tylko bezpośrednio korzystać MDB2?

Przykładowo
  1. <?php
  2. require('MDB2');
  3.  
  4. $db = MDB2->singleton();
  5.  
  6. $db->query('');
  7.  
  8. ...
  9. ?>


czy jak teraz tego singletona wykorzystać w tym momencie?
olechafm
to zależy, co potrzebujesz zrobić, opisane są 3 funkcje i każda z nich zwraca instancję, factory() nie nawiązuje połączenia, connect() nawiązuje gdy już masz np. zainicjowany ten obiekt, a singleton w tym wypadku robi to tak jak Ty chcesz to wykorzystać
Marys91
To może inaczej. Czytałem właśnie artykuł o abstrakcyjnej klasie obsługującej bazę, m.in. wzorzec singletona. Mi głównie chodzi o to, aby nie łączyć się z bazą za każdym razem.
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.