Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Ocena klasy obsługującej baze danych
rubin1994
post 1.09.2013, 16:42:50
Post #1





Grupa: Zarejestrowani
Postów: 4
Pomógł: 0
Dołączył: 1.09.2013

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


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);
Go to the top of the page
+Quote Post
Wazniak96
post 2.09.2013, 11:14:20
Post #2





Grupa: Zarejestrowani
Postów: 550
Pomógł: 75
Dołączył: 5.06.2012
Skąd: Lębork

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


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.
Go to the top of the page
+Quote Post
rubin1994
post 2.09.2013, 14:54:31
Post #3





Grupa: Zarejestrowani
Postów: 4
Pomógł: 0
Dołączył: 1.09.2013

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


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. }
Go to the top of the page
+Quote Post
Wazniak96
post 2.09.2013, 15:08:56
Post #4





Grupa: Zarejestrowani
Postów: 550
Pomógł: 75
Dołączył: 5.06.2012
Skąd: Lębork

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


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.
Go to the top of the page
+Quote Post
ssstrz
post 2.09.2013, 16:43:47
Post #5





Grupa: Zarejestrowani
Postów: 103
Pomógł: 17
Dołączył: 15.12.2012

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


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

Ten post edytował ssstrz 2.09.2013, 16:44:40
Go to the top of the page
+Quote Post
rubin1994
post 2.09.2013, 19:01:42
Post #6





Grupa: Zarejestrowani
Postów: 4
Pomógł: 0
Dołączył: 1.09.2013

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


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. }
Go to the top of the page
+Quote Post
Spawnm
post 2.09.2013, 19:08:33
Post #7





Grupa: Moderatorzy
Postów: 4 069
Pomógł: 497
Dołączył: 11.05.2007
Skąd: Warszawa




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?
Go to the top of the page
+Quote Post
rubin1994
post 13.09.2013, 13:29:48
Post #8





Grupa: Zarejestrowani
Postów: 4
Pomógł: 0
Dołączył: 1.09.2013

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


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
Go to the top of the page
+Quote Post
Crozin
post 13.09.2013, 13:41:25
Post #9





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

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


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ą.
Go to the top of the page
+Quote Post
em1X
post 27.09.2013, 11:35:41
Post #10





Grupa: Zarejestrowani
Postów: 984
Pomógł: 41
Dołączył: 16.03.2002
Skąd: Płock

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


Ł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. }


Ten post edytował em1X 27.09.2013, 11:55:10


--------------------
eh, co polska wódka to polska wódka
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 Wersja Lo-Fi Aktualny czas: 15.08.2025 - 04:05