Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [SQL / PDO...] Powtarzający się kod
terabit
post
Post #1





Grupa: Zarejestrowani
Postów: 170
Pomógł: 4
Dołączył: 11.08.2006

Ostrzeżenie: (10%)
X----


Witam (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

mam np taki oto kod:

  1. <?php
  2. public function getOnePerson($id) {
  3.        
  4.        try {
  5.            
  6.            $pdo = new PDO('mysql:host=localhost;dbname=contactmanager', 'root', 'root');
  7.            $pdo -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  8.            $row = $pdo -> query("SELECT * FROM persons WHERE id = $id");
  9.  
  10.            return $row;
  11.            
  12.        } catch (PDOException $e) {
  13.            echo 'Error:' . $e->getMessage();    
  14.        }
  15.        
  16.        $row -> closeCursor();
  17.        
  18.    }
  19. ?>


i nasuwa się pytanie, co zrobić żeby tego tyle razy nie powtarzać ?
mam jakąś tam klase do zarządzania Osobami i praktycznie w każdej metodzie musze powtarzać ten sam fragment kodu...

jak wy to rozwiązujecie?
czy poprostu zrobić dodatkową metodę do której będę przekazywać coś takiego:
  1. <?php
  2. $row = $pdo -> query("SELECT * FROM persons WHERE id = $id");
  3. ?>

choć to pewnie nia zawsze się sprawdzi...

pisząc obiektowo raczej nie powinno się powtarzać kilka razy (DRY;))

jakieś rozwiązanie ?

z góry dzięki za pomoc (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 4)
Zyx
post
Post #2





Grupa: Zarejestrowani
Postów: 952
Pomógł: 154
Dołączył: 20.01.2007
Skąd: /dev/oracle

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


Czy ja dobrze widzę, że łączysz się z bazą za każdym razem, gdy chcesz coś z niej pobrać? Jeśli tak, to czym prędzej skasuj ten kod i przepisz go porządnie (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) . Z bazą skrypt powinien się łączyć jedynie raz i tyle. Odpadnie Ci przy okazji problem "powtarzania", do którego mam taką uwagę, że jest pewna granica, do której DRY ma zastosowanie.
Go to the top of the page
+Quote Post
terabit
post
Post #3





Grupa: Zarejestrowani
Postów: 170
Pomógł: 4
Dołączył: 11.08.2006

Ostrzeżenie: (10%)
X----


Czy tak będzie lepiej ? :
  1. <?php
  2. public $pdo;
  3.    
  4.    public function __construct() {
  5.  
  6.        $this->pdo = new PDO('mysql:host=localhost;dbname=.....', 'root', 'root');
  7.        $this->pdo -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  8.        
  9.    }
  10.    
  11.  
  12.    public function getOnePerson($id) {
  13.  
  14.        try {
  15.  
  16.            $row = $this->pdo -> query("SELECT * FROM persons WHERE id = $id");
  17.            return $row;
  18.            
  19.        } catch (PDOException $e) {
  20.            echo 'Error:' . $e->getMessage();    
  21.        }
  22.        
  23.    }
  24.  
  25.  
  26.    public function __destruct() {
  27.        
  28.        $row -> closeCursor();
  29.        
  30.    }
  31. ?>
Go to the top of the page
+Quote Post
megawebmaster
post
Post #4





Grupa: Zarejestrowani
Postów: 143
Pomógł: 17
Dołączył: 8.11.2008
Skąd: Libiąż

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


W __construct() też musisz mieć try ... catch() bo tak nakazuje manual (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) No i po wywołaniu zapytania powinieneś robić $row -> closeCursor(); a nie dopiero w destruktorze (uruchamia on się dopiero wtedy, kiedy niszczony jest obiekt/kończy działanie aplikacja)
Go to the top of the page
+Quote Post
Methestel
post
Post #5





Grupa: Zarejestrowani
Postów: 46
Pomógł: 10
Dołączył: 30.06.2008

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


  1. <?php
  2. class PdoFactory {
  3.    private static $instance = NULL;
  4.    private function __construct() {}
  5.    public static function get() {
  6.        if (self::$instance === NULL) {
  7.            $dsn = 'mysql:dbname=***;host=***;port=***;'; //
  8.            $user = 'nobody';                              //zmien na swoje
  9.            $password = 'nobody';                         //
  10.            try {
  11.                $pdo = new PDO($dsn, $user, $password);
  12.                $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  13.            } catch (PDOException $e) {
  14.                throw new Exception ($e->getMessage());
  15.            }
  16.            self::$instance = $pdo;
  17.        }
  18.        return self::$instance;
  19.    }
  20. }
  21. ?>


Nazwa klasy wskazuje że jest to fabryka bo bardzo łatwo przerobić tą klasę tak żeby fabryką była (fabryka czyli klasa która serwuje różne obiekty w zależności od parametrów) i jeśli w projekcie korzystasz z więcej niż jednej bazy danych należałoby przekazać do metody PdoFactory::get() jeszcze jeden parametr dzięki któremu będziesz mógł uzyskać połączenie z określoną bazą danych

Zaprezentowany wyżej kod jest implementacją wzorca projektowego o nazwie Singleton i sprawdza się bardzo do kodu który ma być dostępny w dowolnym miejscu twojego skryptu. Jest to tak naprawdę opakowana w klasę zmienna globalna dlatego radze nie nadużywać tego wzorca.

Mając tak zdefiniowaną klasę obiekt klasy PDO pobierasz przez:

  1. <?php
  2. $pdo = PdoFactory::get();
  3. ?>


Metoda z twojego pierwszego postu może wyglądać teraz np tak:

  1. <?php
  2. public function getOnePerson($id) {
  3.        
  4.        $pdo = PdoFactory::get();
  5.           //Jeżeli do zapytania przekazujesz jakikolwiek parametr radze zamiast z PDO::query() skorzystać z PDO::prepare()
  6.            $row = $pdo -> query("SELECT * FROM persons WHERE id = $id");
  7.  
  8.            return $row;
  9.        
  10.        $row -> closeCursor(); //to jest bez sensu bo nigdy nie będzie wykonane przez to że umieściłeś to za "return"
  11.        
  12.    }
  13. ?>


albo obiekt klasy PDO pobrać już w samym konstruktorze i przypisać go do prywatnej składowej tej klasy.

Pozwoliłem dodać sobie dwa komentarze do kodu na jego temat.

Ten post edytował Methestel 8.04.2009, 17:43:29
Go to the top of the page
+Quote Post

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: 20.12.2025 - 15:37