Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Ocena klasy obsługującej baze danych
Forum PHP.pl > Forum > PHP > Object-oriented programming
rubin1994
Witam.

Dopiero zacząłem swoją przygodę z objektowym PHP, nie wiem czy do końca dobrze rozumię zasady w nim panujące. Byłbym wdzięczny jeżeli osoba która zna się na tym, mogła mi powiedzieć gdzie popełniłem błędy (mimo tego że skrypt działa tak jak chcę, pewnie jakieś się znajdą).

Klasa ma być odpowiedzialna za dodawanie treści do bazy danych, oraz ich późniejsze wyświetlanie. Aktualnie napisałem tylko dwie metody, ponieważ nie wiem czy dobrze realizuję założenia programowania obiektowego.

  1. class newsSystem {
  2.  
  3. public $title;
  4. public $short_content;
  5. public $content;
  6. public $id;
  7.  
  8. function addNews() {
  9. $connect = new mysqli("localhost", "root", "", "index");
  10. $connect->set_charset('utf8');
  11.  
  12. $connect->query("INSERT INTO news(title, short_content, content) VALUES ('".$this->title."', '".$this->short_content."', '".$this->content."')");
  13. }
  14.  
  15. function showNewsById($id) {
  16. $connect = new mysqli("localhost", "root", "", "index");
  17. $connect->set_charset('utf8');
  18.  
  19. $result = $connect->query("SELECT * FROM news WHERE id=". $id ."");
  20.  
  21. while($row = $result->fetch_array()) {
  22. echo $row['id'] . "<br />";
  23. echo $row['title'] . "<br />";
  24. echo $row['short_content'] . "<br />";
  25. echo $row['content'];
  26. }
  27. }
  28.  
  29. }
  30.  
  31. $editNews = new newsSystem();
  32.  
  33. // Dodawanie newsa
  34. $editNews->title = "TYTUŁ <br />";
  35. $editNews->short_content = "KRÓTKA TREŚĆ <br />";
  36. $editNews->content = "TREŚĆ";
  37. $editNews->addNews();
  38.  
  39. // Wyswietlanie newsa po id
  40. $editNews->showNewsById(19);
Wazniak96
1. W klasie nie łączymy się z bazą, a już na pewno nie w każdej metocie osobno. Utwórz prywatne pole db i wrzuć do niego obiekt bazy danych przez wstrzykiwanie.
2. Klasa nie powinna niczego wyświetlać, może zwrócić dane.
rubin1994
Dzięki za odpowiedź.
Jeżeli chodzi o 2. punkt, myślę że teraz chyba jest dobrze. Odnośnie 1. - nie za bardzo wiem czy dobrze zrobiłem, pierwszy raz spotkałem się z terminem "wstrzykiwania", w internecie za dużo mi się na ten temat znaleźć nie udało; już nie łączę się z bazą w klasie (pewnie i ten sposób jest do poprawy).

  1. class newsSystem {
  2.  
  3. public $title;
  4. public $short_content;
  5. public $content;
  6. public $id;
  7. public $db;
  8.  
  9. function addNews($db) {
  10.  
  11. $db->query("INSERT INTO news(title, short_content, content) VALUES ('".$this->title."', '".$this->short_content."', '".$this->content."')");
  12. }
  13.  
  14. function showNewsById($id) {
  15.  
  16. $result = $this->db->query("SELECT * FROM news WHERE id=". $id ."");
  17.  
  18. return $result;
  19. }
  20.  
  21. }
  22.  
  23. $editNews = new newsSystem();
  24. $editNews->db = new mysqli("localhost", "root", "", "index");
  25.  
  26. // Dodawanie newsa
  27. $editNews->title = "TYTUŁ <br />";
  28. $editNews->short_content = "KRÓTKA TREŚĆ <br />";
  29. $editNews->content = "TREŚĆ";
  30.  
  31. // Wyswietlanie newsa po id
  32.  
  33. $wynik = $editNews->showNewsById(19);
  34.  
  35. while($row = $wynik->fetch_array()) {
  36. echo $row['id'] . "<br />";
  37. echo $row['title'] . "<br />";
  38. echo $row['short_content'] . "<br />";
  39. echo $row['content'];
  40. }
Wazniak96
Drugi wynik z google pod zapytaniem wstrzykiwanie oop php ;p klik

możesz zwrócić tablicę danych a nie obiekt wynikający z metody query.
ssstrz
Co do nowego komponentu ktory tworzysz a uzycie DI polecam przeczytac:
http://docs.phalconphp.com/en/latest/reference/di.html

mysle ze swietnie Ci to wytlumaczy dependency injection w praktyce smile.gif
rubin1994
Wielkie dzięki za rady i artykuły. Poczytałem i sądze, że sposób w jaki teraz to robię jest odpowiedni (mam nadzieję smile.gif). Czy są jeszcze jakieś niedociągnięcia oraz miejsca, które dało by radę jeszcze troche zoptymalizować?

  1. class newsSystem {
  2. private $db;
  3. public $title;
  4. public $short_content;
  5. public $content;
  6. public $id;
  7.  
  8. function addNews($db){
  9. $db->query("INSERT INTO news(title, short_content, content) VALUES ('".$this->title."', '".$this->short_content."', '".$this->content."')");
  10. }
  11.  
  12. function showNewsById($db, $id) {
  13. $wiersz = $db->query("SELECT * FROM news WHERE id=". $id ."");
  14. //$wynik = $wiersz->fetch_array(MYSQL_ASSOC);
  15. $wynik = $wiersz->fetch_assoc();
  16.  
  17. return $wynik;
  18. }
  19. }
  20.  
  21. $connect = new mysqli("localhost", "root", "", "index");
  22.  
  23. $editNews = new newsSystem();
  24.  
  25. //Dodanie newsa
  26. $editNews->title = "Tytuł";
  27. $editNews->short_content = "Krótka";
  28. $editNews->content = "Treść";
  29. $editNews->addNews($connect);
  30.  
  31. //Wyświetlenie pojedyńczego newsa
  32. $newsById = $editNews->showNewsById($connect, 23);
  33. foreach ($newsById as $indeks => $showNews) {
  34. echo "newsById[$indeks] = $showNews <br />";
  35. }
Spawnm
Tak na szybko:

Czemu wszędzie przekazujesz $connect?

Daj proteted $_db; i metodę setDb($db);
Potem w metodach używasz $this->_db->query()

Skoro klasa nazywa się news, po co w każdej metodzie zaznaczasz że operujesz na newsach?
rubin1994
Dzięki za cierpliwość smile.gif
Nawet się już nie pytam czy teraz dobrze, tylko czy teraz lepiej jest napisany ten kod? biggrin.gif

  1. class newsSystem {
  2.  
  3. public $title;
  4. public $short_content;
  5. public $content;
  6. public $id;
  7. private $db;
  8.  
  9. function connectDb($connect) {
  10. $this->db = $connect;
  11. }
  12.  
  13. function add() {
  14. $this->db->query("INSERT INTO news(title, short_content, content) VALUES ('".$this->title."', '".$this->short_content."', '".$this->content."')");
  15. }
  16.  
  17. function showById($id) {
  18. $wiersz = $this->db->query("SELECT * FROM news WHERE id=". $id ."");
  19. $wynik = $wiersz->fetch_assoc();
  20.  
  21. return $wynik;
  22. }
  23.  
  24. }
  25.  
  26. $news = new newsSystem;
  27.  
  28. $connection = new mysqli("localhost", "root", "", "index");
  29.  
  30. $news->connectDb($connection);
  31.  
  32. //Dodawanie newsa
  33. $news->title = "tytul";
  34. $news->short_content = "short";
  35. $news->content = "content";
  36.  
  37. $news->add();
  38.  
  39. //Wyswietlanie newsa po id
  40. $newsById = $news->showById(23);
  41. foreach ($newsById as $indeks => $showNews) {
  42. echo "newsById[$indeks] = $showNews <br />";
  43. }


@up
Crozin
Jest on bardzo źle napisany, zawiera luki w bezpieczeństwie oraz nie ma nic wspólnego z OOP. Wymyślono już dawno temu ORM-y, które rozwiązują Twoje problemy, a do tego są napisane poprawnie - dlaczego z nich nie skorzystasz? Uprzedzając jeszcze: 1) dużo szybciej nauczysz się znaczenie więcej 2) kod będzie działał i nie rzucał kłód pod nogi na każdym kroku 3) przy okazji poznasz i zyskasz doświadczenie w pracy z daną biblioteką.
em1X
Łamiesz przede wszystkim zasadę Single Responsibility Principle. To jest ciągle kod proceduralny tylko opakowany w klasę i nie ma (prawie) nic wspólnego z obiektowością. Bez zagłębiania się w kod klas finalnie byłoby lepiej, gdyby wyglądało to tak:

  1. // wzorzec factory tworzy nam nowy obiekt Wpisu
  2. $post=NewsFactory::create('Post');
  3. $post->setTitle('Tytuł wpisu');
  4. $post->setShort('Lorem...');
  5. $post->setBody('Lorem ipsum..');
  6.  
  7. // uruchamiamy silnik bazy, w tym przypadku SQL
  8. // ale nic nie stoi na przeszkodzie, żeby podstawić inny silnik bez zmiany kodu
  9. $sql_connection=new SqlConnection('localhost', 'user', 'haslo');
  10.  
  11. // albo:
  12. // $sql_connection=new OracleConnection();
  13. // $sql_connection=new FlatFileDatabase();
  14. // $sql_connection=new CookieDatabase();
  15. // itd.
  16.  
  17. // uruchamiamy wrapper bazy, który odpowiada za operacje
  18. // na systemie bazodanowym (lub każdym innym)
  19. $db_wrapper=new DbWrapper($sql_connection);
  20.  
  21. // zapisz post
  22. $db_wrapper->save($post);
  23.  
  24. // pobierz post z bazy
  25. $post_z_bazy=$db_wrapper->getById(1);


Klasa SqlConnection powinna implementować jakiś stabilny interfejs typu:
  1. interface PersistentStorage
  2. {
  3. /**
  4.   * Zapisz dane do magazynu.
  5.   * @return bool Czy zapis się powiódł.
  6.   */
  7. public function save($object);
  8.  
  9. /**
  10.   * Pobierz dane przez klucz główny.
  11.   * @return mixed Pobrany rekord
  12.   */
  13. public function getById($id);
  14. }
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.