Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [SQL / PDO...] Powtarzający się kod
Forum PHP.pl > Forum > PHP
terabit
Witam 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 winksmiley.jpg
Zyx
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 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.
terabit
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. ?>
megawebmaster
W __construct() też musisz mieć try ... catch() bo tak nakazuje manual 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)
Methestel
  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.
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.