Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Rozszerzanie klasy PDO - propozycja
Forum PHP.pl > Forum > PHP > Object-oriented programming
elnino.pl
Co myślicie o poniższym kodzie:

  1. <?php
  2. class db extends PDO
  3. {
  4. public function singleton()
  5. {
  6. static $instance;
  7. if(!isset($instance))
  8. $instance = new db;
  9. return $instance;
  10. }
  11.  
  12. function __construct()
  13. {
  14. require_once('../config.php5');
  15. parent::__construct($dbd['type'] . ':host=' . $dbd['server'] . ';dbname=' . $dbd['db'], $dbd['user'], $dbd['pass']);
  16. parent::query("SET CHARACTER SET utf8"); 
  17. define('P', $dbd['prefix']);
  18. }
  19. }
  20. ?>


Niby wszystko działa tak jak chcę, ale w jaki sposób mam zabijać uchwyt do bazy? Czyste pdo niszczyłem poprzez $obiektPDO = null - A w tej chwili nie bardzo wiem jak to zrobić. Próbowałem wywołać destruktor PDO w destruktorze mojej klasy, ale okazało się, że PDO nie posiada destruktora. Nie chcę, żeby mi "zwisały" otwarte połączenia z bazą. Pamiętam, że przy standardowych połączeniach z bazą miałem z tym problem. Czasem zapominałem kończyć połączenia.
bigZbig
Po pierwsze ta klasa nie jest Singletonem ponieważ mozna utworzyć wiecej niż jedną jej instancję.

Po drugie brak deklaracji wlasciwosci statycznych

Po trzecie gdyby to byl singleton to nie mialbys problemu ze "zwisającymi" otwartymi polaczeniami z baza bo byloby tylko jedno polaczenie.

Po czwarte - destrukcja $obiektDB = null; i po sprawie
elnino.pl
Nie jest singletonem, bo php odmawia oznaczenia konstruktora jako prywatny.
bigZbig
A czytales temat Singleton i dziedziczenie?
elnino.pl
Czytałem. Z tego, co zrozumiałem w wersji 5.1.4 nie da się tego obejść.
bigZbig
Czytaj do konca. Poza tym nie zmienia to faktu, ze Twoja klasa zawiera bledy formalne. Poczytaj na temat implementacji wzorca singleton.

Pokaz mi jak uzywasz swojej klasy.
elnino.pl
Chodzi Ci o wersję cvs?

  1. <?php
  2.  
  3. $dbr = db::singleton();
  4.  
  5. ?>


W sumie czytałem o singletonach tutaj: http://webcity.pl/webcity/artykuly.php/t/62

O jakie błędy formalne Ci chodzi?
bigZbig
Cytat(elnino.pl @ 21.07.2006, 12:33 ) *
  1. <?php
  2. $dbr = db::singleton();
  3. ?>

Spojrz na swoja klase i na sposob uzycia? Czy wszysko Ci tu pasuje? Poza tym przeczytaj jeszcze raz moj pierwszy post w tym temacie.

-- edit --
Zobacz Singleton
NuLL
elnino - po co stosujesz zmienna statyczna metody skoro w php5 mamy prywatne wlasnosci statyczne questionmark.gif
elnino.pl
Dzięki za pomoc. A jak w takim razie rozwiązać kwestię zabijania obiektu? Czy muszę używać "$dbr = null" ? Nie dałoby się tego prościej zrobić?

-- edit --

Fatal error: Access level to db::__construct() must be public (as in class PDO) in /XXX/class.Db.php5 on line 27
bigZbig
O co Ci chodzi z tym destruktorem? Obiekt Twojej klasy to pod wzgledem destrukcji taki sam obiekt jak kazdy inny i tak samo go traktuj.

Pokarz jak wyglada Twoja klasa po zmianach. Przetestuje ją u siebie.
elnino.pl
  1. <?php
  2. class db extends PDO
  3. {
  4. private static $instance;
  5.  
  6. public static function singleton()
  7. {
  8. if(!isset(self::$instance))
  9. self::$instance = new db();
  10. return self::$instance;
  11. }
  12.  
  13. public function __construct()
  14. {
  15. require_once('../config.php5');
  16. parent::__construct($dbd['type'] . ':host=' . $dbd['server'] . ';dbname=' . $dbd['db'], $dbd['user'], $dbd['pass']);
  17. parent::query("SET CHARACTER SET utf8"); 
  18. define('P', $dbd['prefix']);
  19. define('HASH', $dbd['hash']);
  20. }
  21. }
  22. ?>

Public, bo na private się sypie.

I jeszcze jeden kłopot mam z innym kontruktorem. Klasa implementuje interfejs:
  1. <?php
  2. interface action
  3. {
  4. function __construct();
  5. function __destruct();
  6.  
  7. static function process();
  8. }
  9.  
  10. class page_view_action implements action
  11. {
  12. //
  13. private static $instance;
  14.  
  15. public static function process()
  16. {
  17. if(!isset(self::$instance))
  18. self::$instance = new page_view_action();
  19. return self::$instance;
  20. }
  21.  
  22. private function __construct()
  23. {
  24. //
  25. }
  26.  
  27. public function __destruct()
  28. {
  29.  
  30. }
  31. }
  32. ?>


Dla powyższego kodu mam bląd: "Fatal error: Access level to page_view_action::__construct() must be public (as in class Action)"

Jeśli zmienię w interfejsie konstruktor na prywatny dostaję błąd: "Fatal error: Access type for interface method Action::__construct() must be omitted"
bigZbig
1. Konstruktor klasy db musi byc publiczny poniewaz konstruktor klasy PDO jest publiczny (zapewne implementuje jakis interfejs, ktory tego wymaga).

2. W interfejsie definiuje sie jedynie metody publiczne. Do tego sluzy interfejs - chodzi o to, ze dany obiekt komunikuje sie ze swiatem zewnetrznym za pomoca metod publicznych. Dlatego nie mozesz w intefejsie zadeklarowac metody prywatnej lub chronionej. Wyrzuc konstruktor i destruktor z interfejsu.
elnino.pl
Dzięki. Nadal jednak nie wiem co z tym zabiciem uchwytu do bazy danych. Czy muszę null'ować zmienną?
bigZbig
Zamiast Twojej klasy sprobuj tego (pisane z reki)
  1. <?php
  2. class db
  3. {
  4. private static $instance = false;
  5.  
  6. public static function singleton()
  7. {
  8. if((self::$instance === false))
  9. self::$instance = db::createPdoInstance();
  10. return self::$instance;
  11. }
  12.  
  13. private function __construct()
  14. {}
  15.  
  16. private static function createPdoInstance()
  17. {
  18. require_once('../config.php5');
  19. $db = new PDO($dbd['type'] . ':host=' . $dbd['server'] . ';dbname=' . $dbd['db'], $dbd['user'], $dbd['pass']);
  20. $db->query("SET CHARACTER SET utf8");
  21. define('P', $dbd['prefix']);
  22. define('HASH', $dbd['hash']);
  23. return $db;
  24. }
  25. }
  26. $db = db::singleton();
  27. ?>


Co do niszczenia polaczenia. Skoro masz tylko jedno to pozwol mu zwyczajnie wygasnac przy zakonczeniu skryptu.

-- edit --
Klasa db nie moze byc rozszerzeniem klasy PDO
elnino.pl
Niestety to samo.

A jeśli chodzi o niszczenie - kiedyś miałem kłopot, bo otwierałem połączeina mysql (standardowo) i na końcu ich nie zamykałem. Administrator serwera powiedział, że te wszystkie połączenia "wiszą" ciągle otwarte (pomimo tego, że nie były pconnect)...
bigZbig
Zrobilem poprawki zapomnialem usunac extends PDO

Patrz wyzej
elnino.pl
Dzięki, gra i buczy!
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.