Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Czy warto stosować PEAR::DB w OOP oraz czy przechowywać dane w tabliczy czy w osobnych zmiennych ?
become
post
Post #1





Grupa: Zarejestrowani
Postów: 88
Pomógł: 0
Dołączył: 12.01.2007

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


mam taką klasę

  1. <?php
  2. class Autor() {
  3.  
  4.  var $oDB=null; # obiekt PEAR:(IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif) B;
  5.  var $aAutor=null; # zmienna przechowujaca dane autora
  6.  
  7.  function Autor($oDB=null) {
  8. if (!is_null($oDB)) $this->oDB=$oDB;
  9.  }
  10.  
  11.  function dbGetAutorById($id=null) {
  12.  
  13. if (is_null($id) return null;
  14.  
  15. $aQ="
  16.  SELECT *
  17.  FROM autor
  18.  WHERE id=?
  19. ";
  20.  
  21. $aA=$this->oDB->getRow($sQ, array($id), DB_FETCHMODE_ASSOC);
  22. if (is_array($aA) and count($aA)==1) $this->aAutor=$aA;
  23.  }
  24. }
  25. ?>


i pozniej sposob wykorzystania tego

  1. <?php
  2. include "PEAR/DB.php"; 
  3.  
  4.  $oDB=new DB();
  5.  $oDB->connect(DSN);
  6.  
  7.  $autor=new Autor($oDB);
  8.  $autor->dbGetAutorById(234);
  9. ?>


mam pytanie. czy mozna ją tą zbudować ? czy uzycie obiektu klasy PEAR:: DB i przekazanie jej do innej klasy w powyzszy sposob jest prawidlowe ? Czy wogole warto uzywać pakiet PEAR:: DB cyz moze cos innego ?

Drugie pytanie. Czy reprezentawac dane autora jako tablice czy raczej stworzyc osobne zmienne na np. pole imie, nazwisko, email, ktore bedą reprezentowac kolumny w tabeli ?

Ten post edytował become 28.11.2007, 13:22:02
Go to the top of the page
+Quote Post
NoiseMc
post
Post #2





Grupa: Zarejestrowani
Postów: 398
Pomógł: 10
Dołączył: 24.11.2004
Skąd: Łódź

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


Ja mam osobno Data Objects i Data Access Objects. Data Objects przechowuja tylko dane, a Data Access Objects pobieraja dane z bazy i na ich podstawie zwracaja tablice wypelnionych danymi z bazy Data Objects czyli na przyklad:
  1. <?php
  2. class Products_Product
  3. {
  4. public $productID;
  5. public $categoryID;
  6. public $name;
  7. public $urlSlug;
  8. public $copy;
  9. public $displayOrder;
  10.  
  11.  public function __construct ($productID = null, $categoryID = null, $name = null, $urlSlug = null, $copy = null, $displayOrder = null
  12. {
  13. $this->productID = $productID;
  14. $this->categoryID = $categoryID;
  15. $this->name = $name;
  16. $this->urlSlug = $urlSlug;
  17. $this->copy = $copy;
  18. $this->displayOrder = $displayOrder;
  19. }
  20. }
  21. ?>

  1. <?php
  2. class Products_Model extends Base_Model 
  3. {
  4. public function getAll ()
  5. {
  6. $query = 'SELECT * FROM ' . $this->config->database->prefix . 'products ORDER BY DisplayOrder DESC';
  7.  
  8. $statement = $this->db->prepare ($query);
  9.  
  10. $statement->execute ();
  11.  
  12. while ($product = $statement->fetch ())
  13. {
  14. $products[] = new Products_Product ($product['ProductID'], $product['CategoryID'], $product['Name'], $product['UrlSlug'], $product['Copy'], $product['DisplayOrder'], $product['MetaTitle'], $product['MetaDescription'], $product['MetaKeywords']);
  15. }
  16.  
  17. if (empty ($products))
  18. {
  19. return null;
  20. }
  21.  
  22. return $products;
  23. }
  24. }
  25. ?>

Co do DB to uzywam PDO, ma chyba taka sama funkcjonalnosc jak PEAR:DB, a jest wbudowane w PHP 5 i obiekt DB tworze sobie w klasie bazowej dla Data Access Object:
  1. <?php
  2. class Base_Model 
  3. {
  4. protected $db;
  5. protected $config;
  6.  
  7. public function __construct ()
  8. {
  9. $this->config = Zend_Registry::get ('config');
  10.  
  11. $this->db = new PDO ('mysql:host=' . $this->config->database->host . ';dbname=' . $this->config->database->dbname . '', $this->config->database->username, $this->config->database->password);
  12.  
  13. $this->db->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  14. $this->db->setAttribute (PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1);
  15. }
  16. }
  17. ?>


Korzystam z tego tak:
  1. <?php
  2. $productsModel = new Products_Model ();
  3. $products = $productsModel->getAll ();
  4. ?>

Jezeli w przyszlosci chcialbym zmienic PDO na PEAR:DB to zmieniam to tylko w klasie bazowej dla modelu ... ewentualnie wyrownuje niespojnosc w API obu bibliotek piszac sobie fasade DB_Adapter ktory korzysta z PEAR:(IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif) B ale ma API identyczne jak PDO. Zmiana biblioteki DB odbywa sie bez naruszenia pozostalych klas i tylko w klasie bazowej dla Data Access Objects

Ten post edytował NoiseMc 28.11.2007, 15:12:41
Go to the top of the page
+Quote Post
become
post
Post #3





Grupa: Zarejestrowani
Postów: 88
Pomógł: 0
Dołączył: 12.01.2007

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


aaa kumam, czyli proponujesz stworzyc klase reprezentujaca model danych usera oraz osobno klase reprezentujaco sam user.
a klasa model usera bylaby rozszerzeniem klasy bazowej model.

To ma sens jezeli zapytania sformatujesz tak jak napisales, bo np. w PDO nie ma mozliwości stworzenia zapytan tak jak w PEAR:(IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif) B (IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif)
Np. w PEAR:(IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif) B w zapytaniu można stosować znak zapytania, ktory zostaje zamieniony na odpowiednie wartosci z tablicy parametrów, ktorą to tablice przekazujesz do metody np. getAll.
No ale to szczegol.

A jak reprezentowac dane w klasie?

Np. jezeli mam USER'a, który w bazie SQL ma imie, nazwisko, email

To czy lepiej jest w klasie USER utworzyć jedną zmienną, która będzie przechowywać tablice zawierajacą wszystkie informacje na temat usera, czy w klasie stworzyć osbne zmienne dla imie, nazwisko, email i podstawić do nich dane z wyniku zapytania ?

Ten post edytował become 28.11.2007, 15:58:42
Go to the top of the page
+Quote Post
NoiseMc
post
Post #4





Grupa: Zarejestrowani
Postów: 398
Pomógł: 10
Dołączył: 24.11.2004
Skąd: Łódź

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


Ja jestem za tym zeby kazdy rekord z bazy byl reprezentowany jako obiekt z wlasciwosciami ... jakos tak bardziej mi czysto i ladnie wyglada.
Co do znakow zapytania to pewnie masz na mysli paramertyzowane zapytania ... i tak tez jest to mozliwe w PDO na dwa sposoby, wiecej tutaj: http://de2.php.net/pdo-prepare.

U mnie to wyglada tak:
  1. <?php
  2. class Products_Model extends Base_Model 
  3. {
  4. public function save (Products_Product $product)
  5. {
  6. $query = 'SELECT MAX(DisplayOrder) AS DisplayOrder FROM ' . $this->config->database->prefix . 'products LIMIT 1';
  7.  
  8. $statement = $this->db->prepare ($query);
  9. $statement->execute ();
  10.  
  11. $result = $statement->fetch ();
  12.  
  13. $maxDisplayOrder = ++$result['DisplayOrder'];
  14.  
  15. if (isset ($product->productID))
  16. {
  17. $query = 'UPDATE ' . $this->config->database->prefix . 'products SET CategoryID = ?, Name = ?, UrlSlug = ?, Copy = ?, MetaTitle = ?, MetaDescription = ?, MetaKeywords = ? WHERE ProductID = ?';
  18. }
  19. else 
  20. {
  21. $query = 'INSERT INTO ' . $this->config->database->prefix . 'products (CategoryID, Name, UrlSlug, Copy, MetaTitle, MetaDescription, MetaKeywords, 
    DisplayOrder) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'
    ;
  22. }
  23.  
  24. $statement = $this->db->prepare ($query);
  25.  
  26. $statement->bindParam (1, $product->categoryID);
  27. $statement->bindParam (2, $product->name);
  28. $statement->bindParam (3, $product->urlSlug);
  29. $statement->bindParam (4, $product->copy);
  30. $statement->bindParam (5, $product->metaTitle);
  31. $statement->bindParam (6, $product->metaDescription);
  32. $statement->bindParam (7, $product->metaKeywords);
  33.  
  34. if (isset ($product->productID))
  35. {
  36. $statement->bindParam (8, $product->productID);
  37. }
  38. else 
  39. {
  40. $statement->bindParam (8, $maxDisplayOrder);
  41. }
  42.  
  43. $statement->execute ();
  44.  
  45. if (isset ($product->productID))
  46. {
  47. return $product->productID;
  48. }
  49. else 
  50. {
  51. return $this->getLastInsertID ();
  52. }
  53. }
  54. }
  55. ?>


Ten post edytował NoiseMc 28.11.2007, 16:28:36
Go to the top of the page
+Quote Post
phpion
post
Post #5





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Cytat(become @ 28.11.2007, 17:48:36 ) *
Np. w PEAR:(IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif) B w zapytaniu można stosować znak zapytania, ktory zostaje zamieniony na odpowiednie wartosci

Poczytaj http://pl.php.net/manual/en/ref.pdo.php w szczególności Example#7 Repeated inserts using prepared statements.

Cytat(become @ 28.11.2007, 17:48:36 ) *
A jak reprezentowac dane w klasie?

Np. jezeli mam USER'a, który w bazie SQL ma imie, nazwisko, email

To czy lepiej jest w klasie USER utworzyć jedną zmienną, która będzie przechowywać tablice zawierajacą wszystkie informacje na temat usera, czy w klasie stworzyć osbne zmienne dla imie, nazwisko, email i podstawić do nich dane z wyniku zapytania ?

Zrób tak jak napisał Ci ~NoiseMC. W klasie User opisz z czego składa się obiekt użytkownika (np. private $login, private $password itd), utwórz konstruktor, dopisz gettery i settery i w zasadzie to tyle (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) Natomiast w UserDb przechowuj statyczne metody pobierające dane z bazy i zwracające obiekty typu User (lub tablice obiektów).

// heh, ciut za późno no ale niech już zostanie (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

Ten post edytował phpion.com 28.11.2007, 16:34:03
Go to the top of the page
+Quote Post
NoiseMc
post
Post #6





Grupa: Zarejestrowani
Postów: 398
Pomógł: 10
Dołączył: 24.11.2004
Skąd: Łódź

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


Wlasnie dobrze ze dodales, jeszcze gettery i settery mozna dopisac do klas Data Objects ale to jest juz zupelnie inny temat. (Przydatnosc getterow i setterow)
Go to the top of the page
+Quote Post
phpion
post
Post #7





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




(IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Pisanie getterów i setterów może wydawać się upierdliwe i zbędne (można przecież skorzystać z __get() oraz __set() lub po prostu określić składowe jako public (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) ) jednak przynosi wiele korzyści, o których poczytasz w linku podanym przez ~NoiseMC.

Od siebie dodam jeszcze, że podział modelu na User oraz UserDb jest realizowany np. przez Propel'a (komunikacja z bazą zapisana w UserPeer). Dla mnie osobiście takie rozdzielenie modelu na 2 klasy jest jak najbardziej logiczne. Masz klasę reprezentującą dany obiekt oraz klasę do manipulowania nim (Create Retrieve Update Delete).
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #8





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Cytat
Od siebie dodam jeszcze, że podział modelu na User oraz UserDb jest realizowany np. przez Propel'a (komunikacja z bazą zapisana w UserPeer)


Szkoda tylko jednej rzeczy - słabej zarządzalności tą klasą. Nazwa bazy danych i tabeli zapisana na sztywno w stałej. Gdy zmianisz nazwę bazy danych, to automatycznie musisz generować model od nowa - jest to lekko irytujące podczas fazy testowej.
Go to the top of the page
+Quote Post
phpion
post
Post #9





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Cytat(Cysiaczek @ 28.11.2007, 19:30:50 ) *
Szkoda tylko jednej rzeczy - słabej zarządzalności tą klasą. Nazwa bazy danych i tabeli zapisana na sztywno w stałej. Gdy zmianisz nazwę bazy danych, to automatycznie musisz generować model od nowa - jest to lekko irytujące podczas fazy testowej.

Fakt, zgadzam się, chodziło mi tylko o rozdzielenie modelu na 2 klasy.
Go to the top of the page
+Quote Post
become
post
Post #10





Grupa: Zarejestrowani
Postów: 88
Pomógł: 0
Dołączył: 12.01.2007

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


Widzać, że macie spore pojęcie o OOP. Ja dopiero zacząłem się uczyc. Dzieki za info.

Cytat(NoiseMc @ 28.11.2007, 15:08:23 ) *
Korzystam z tego tak:
  1. <?php
  2. $productsModel = new Products_Model ();
  3. $products = $productsModel->getAll ();
  4. ?>


no dobra. a czy nie lepiej byloby metody klasy Products_Model stworzyc jako statyczne i wywolywac bezposrednio
z klasy ?
  1. <?php
  2.  $products = Products_Model::getAll ();
  3. ?>


Rozumiem ze w tym przypadku model produktow stanowi wzorzec fabryki ?
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: 14.09.2025 - 14:57