Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP] PDO singelton, klasa do obsługi bazy
Pol78
post
Post #1





Grupa: Zarejestrowani
Postów: 3
Pomógł: 0
Dołączył: 16.03.2009

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


Cześć, mam problem z własną klasą do obsługi bazy.

Tymczasowo mam tylko samo połączenie, ale docelowo chciałbym w tej klasie zamieścić uniwersalne metody do wykonywania select'ów / update'ów / etc.

Kod mojej klasy:

  1. <?php
  2. class DB
  3. {
  4.    private static $instance;
  5.  
  6.    private function __construct()
  7.    {
  8.        $dsn_user = 'xxx';
  9.        $dsn_pass = 'yyy';
  10.        $dsn_host = 'zzz';
  11.        $dsn_base = 'www';
  12.  
  13.        try
  14.        {
  15.            self::$instance = new PDO ("mysql:host=" . $dsn_host . ";dbname=" . $dsn_base . ";port=3306", $dsn_user, $dsn_pass);
  16.            self::$instance->exec("SET NAMES UTF8");
  17.        }
  18.        catch (PDOException $e)
  19.        {
  20.            echo "DB error (" . $e->getMessage() . ")";
  21.            exit;
  22.        }
  23.    }
  24.  
  25.    private function __clone() {}
  26.  
  27.    public static function getInstance()
  28.    {
  29.        if (self::$instance === null)
  30.        {
  31.            self::$instance = new self();
  32.        }
  33.        return self::$instance;
  34.    }
  35. }
  36. ?>



I teraz jak próbuje jej użyć:

  1. <?php
  2. require_once( dirname(__FILE__) . '/../class/DB.class.php' );
  3.  
  4.    $db = DB::getInstance();
  5.  
  6.    $r = $db->query("select * from Table");
  7. ?>


to dostaje komunikat: Fatal error: Call to undefined method DB::query().

Może mi ktoś wskazać gdzie popełniam błąd? Z góry dzięki za pomoc!
Go to the top of the page
+Quote Post
wookieb
post
Post #2





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Jak już to rozszerz sobie PDO

Kod
class DB extends PDO

i wtedy dodaj tam singletona.


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





Grupa: Zarejestrowani
Postów: 890
Pomógł: 65
Dołączył: 13.11.2005
Skąd: Olsztyn

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


Cytat
Call to undefined method DB::query()


A co niejasnego jest w tym komunikacie? blinksmiley.gif


@up: Ano

Ten post edytował drPayton 16.03.2009, 00:26:07
Go to the top of the page
+Quote Post
Pol78
post
Post #4





Grupa: Zarejestrowani
Postów: 3
Pomógł: 0
Dołączył: 16.03.2009

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


Cytat(wookieb @ 16.03.2009, 00:22:51 ) *
Jak już to rozszerz sobie PDO

Kod
class DB extends PDO

i wtedy dodaj tam singletona.


No tak, ale w takim przypadku (class DB extends PDO) nie mogę zablokować konstruktora (private function __construct() {}) bo krzyczy mi błędem (Access level to DB::__construct() must be public (as in class PDO)).
Jak w takim przypadku zabezpieczyć klasę przed możliwością tworzenia obiektu?
Go to the top of the page
+Quote Post
Mephistofeles
post
Post #5





Grupa: Zarejestrowani
Postów: 1 182
Pomógł: 115
Dołączył: 4.03.2009
Skąd: Myszków

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


A po co blokować konstruktor? Dopóki tylko ty korzystasz z tego kodu to nie ma takiej potrzeby.
Albo drugie wyjście, zamiast new self daj new PDO(...). Ale to już będzie mniej zgodne z wzorcem.

Ten post edytował Mephistofeles 16.03.2009, 10:25:43
Go to the top of the page
+Quote Post
Pol78
post
Post #6





Grupa: Zarejestrowani
Postów: 3
Pomógł: 0
Dołączył: 16.03.2009

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


Tak się dziś cały dzień zastanawiam nad powyższym rozwiązaniem i wymyśliłem taką mieszankę singeltona i klasy statycznej (o ile można tak to nazwać smile.gif

  1. <?php
  2. class DB
  3. {
  4.    private static $instance;
  5.  
  6.    private function __construct() {}
  7.    private function __clone() {}
  8.  
  9.    private static function getInstance()
  10.    {
  11.        if (self::$instance === null)
  12.        {
  13.            try
  14.              {
  15.                  self::$instance = new PDO ("mysql:host=aaa;dbname=bbb;port=3306", "ccc", "ddd");
  16.                  self::$instance->exec("SET NAMES UTF8");
  17.              }
  18.              catch (PDOException $e)
  19.              {
  20.                  echo "DB error (" . $e->getMessage() . ")";
  21.                  exit;
  22.              }
  23.        }
  24.        return self::$instance;
  25.    }
  26.  
  27.  
  28.    public function query($_sql)
  29.    {
  30.        self::getInstance();
  31.        $_r = self::$instance->prepare($_sql);
  32.        if ( !$_r->execute() )
  33.        {
  34.            echo "DB error (" . $_r->errorInfo() . ")";
  35.            exit;
  36.        }
  37.        return $_r->fetchAll();
  38.    }
  39. }
  40. ?>


I potem wystarczy tylko tyle do użycia:

  1. <?php
  2. $r = DB::query("select * from Table");
  3. ?>


Co sądzicie o takim rozwiązaniu? Ma rację bytu czy raczej przekombinowane?
Go to the top of the page
+Quote Post
Fifi209
post
Post #7





Grupa: Zarejestrowani
Postów: 4 655
Pomógł: 556
Dołączył: 17.03.2009
Skąd: Katowice

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


Ja bym powiedział tak:

Albo klasa statyczna albo nie.

Jeżeli masz metody "niestatyczne" to singleton'a robisz tak:
  1. <?php
  2. private __construct() {
  3. // konstruktor
  4. }
  5.  
  6. public function sing() {
  7. static $handle;
  8. if (!isset($handle)) {
  9. $handle = new nazwaklasy();
  10. }
  11. return $handle
  12. }
  13. ?>


i tworzysz potem obiekt klasy
$test = nazwaklasy::sing();

Ten post edytował fifi209 17.03.2009, 14:35:31


--------------------
Zainteresowania: C#, PHP, JS, SQL, AJAX, XML, C dla AVR
Chętnie pomogę, lecz zanim napiszesz: Wujek Google , Manual PHP
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 22.08.2025 - 08:41