Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wyświetlanie danych z MySQL, a OOP
Forum PHP.pl > Forum > PHP > Object-oriented programming
spokoloko123
Jak poprawnie wyświetlać dane z bazy danych zgodnie z OOP? Czy konstrukcja:
  1. while($this->row = mysql_fetch_accoc){
  2. $zmienna = $this->row['title'];
  3. $zmienna .= $this-row['content'];
  4. }

, a potem wyświetlenie zmiennej jest poprawna w ujęciu programowania obiektowego? Dlaczego, dlaczego nie?
bastard13
W programowaniu obiektowym baza danych to tylko miejsce, w którym dane stałe są zapisywane. Od zarządzania tymi danymi masz modele, czyli klasy, które charakteryzują logikę Twojej aplikacji. Oczywiście musisz posiadać klasę, która stworzy Ci model na podstawie danych z bazy (w Twoim przypadku kolekcje modeli). Może to być osobny obiekt (co jest chyba najlepszym rozwiązaniem) bądź sama klasa modelu może posiadać mechanizm do wyciągania tych danych. Drugie rozwiązanie jest o tyle niezbyt pożądane, że w przypadku, gdy musisz zmienić miejsce przechowywania danych np. z bazy MySQL na pliki XML, to musisz dotykać klas, które powinny być odpowiedzialne jedynie za logikę, a więc niezależne od miejsce przechowywania danych.
markonix
Ostatnio też się nad tym głowiłem.
W różnych mini frameworkach tworzona była klasa model i klasa obiektu np. model i obiekt książki.
Np pobranie 10 książek to utworzenie 10 obiektów typu "książka". Wszystko ładnie i pięknie ale gdy robiłem klasę użytkowników gdzie jeden użytkownik miał ponad 20 atrybutów to konstruktor wyglądał nieciekawie i niestety nie udało mi się utrzymać tej konwencji. PDO (mysql_ też) może zwrócić wiersz jako obiekt ale wydaje mi się to sztucznym rozwiązaniem.

Też jestem ciekaw jak to wygląda w praktyce.
bastard13
@markonix zawsze możesz zastosować Proxy. Np.
10 książek to kolekcja obiektów. Kolekcja też sama w sobie jest obiektem. I przy tworzeniu tej kolekcji wyciągasz podstawowe informacje nt. książek (np. tytuł, + autor). Natomiast jeżeli potrzebujesz wykonać jakieś bardziej złożone operacje na książce, to dopiero tak naprawdę jest tworzony obiekt.
To samo z użytkownikami.
spokoloko123
Gdy do wszystkiego podchodzę od strony obiektu mysqli czyli new mysqli(...) to pojawia się problem i nie jestem zdecydowany do do tego jak go rozwiązać.
Wiadomo, że do mysql łączyć się będę tylko jeden raz, ale obiekty stworzone poza klasą nie są w niej dostępne. Więc moje pytanie jest następujące, czy używać sobie takiemo menadżera, który napisałem:
  1. class MySQLiQueryManager
  2. {
  3. private static $instance;
  4. public function __construct()
  5. {
  6. if(!self::$instance)
  7. {
  8. self::$instance = $this;
  9. $connect_args = func_get_args();
  10. if(count($connect_args) != 4)
  11. {
  12. echo "Nowy egzemplarz musi zawierać host, nazwię użytkownika i jego hasło oraz bazę danych.";
  13. }
  14. self::$instance->db = new mysqli($connect_args[0], $connect_args[1], $connect_args[2], $connect_args[3]);
  15. if(mysqli_connect_errno())
  16. {
  17. echo "Błąd połączenia z baza danych: ".mysqli_connect_error();
  18. }
  19. self::$instance->db -> set_charset("UTF8");
  20. }
  21. else {
  22. $connect_args = func_get_args();
  23. if($connect_args)
  24. {
  25. echo "Tylko nowy egzemplarz może zawierać połączenie!";
  26. }
  27. }
  28. }
  29. public function query($query)
  30. {
  31. return self::$instance->result = self::$instance->db->query($query);
  32. }
  33. }
  34.  
  35. new MySQLiQueryManager("localhost", "root", "", "test");
  36.  
  37. class Users
  38. {
  39. public function getUsers()
  40. {
  41. $user = new MySQLiQueryManager;
  42. $result = $user->query("SELECT * FROM users");
  43. while($row = $result->fetch_row())
  44. {
  45. echo "<pre>";
  46. print_r($row);
  47. echo "</pre>";
  48. }
  49. }
  50. }

i wywoływać ten stary egzemplarz MySQLiQueryManager czy może zostać przy strukturze proceduralnej mysqli na potrzeby użycia w klasach?
ano
Ciekawe podejście do singletona wink.gif

A tak serio to nie musisz robić statycznej instancji połączenia z DB. Wystarczy, że do obiektów typu Users będziesz przekazywał (np. w konstruktorze) instancję MySQLiQueryManager.

Np:
  1.  
  2. class Users
  3.  
  4. {
  5. /**@var MySQLiQueryManager */
  6. protected $queryManager;
  7.  
  8. public function __construct(MySQLiQueryManager $queryManager) {
  9. $this->queryManager = $queryManager;
  10. }
  11.  
  12. public function getUsers()
  13. {
  14.  
  15. $user = $this->queryManager;
  16. $result = $user->query("SELECT * FROM users");
  17.  
  18. while($row = $result->fetch_row())
  19. {
  20. echo "<pre>";
  21. print_r($row);
  22. echo "</pre>";
  23.  
  24. }
  25. }
  26. }


Poza tym używanie func_get_args(); w konstruktorze MySQLiQueryManager to BAAARDZO zły pomysł. Co z podpowiadaniem składni w IDE? Po roku już zapomnisz co musisz przekazać w konstruktorze! Zmień to na __construct($username, $password, $host,...)

Kolejna baaardzo słaba rzecz:
  1. echo "Błąd połączenia z baza danych: ".mysqli_connect_error();


To powinno wyglądać np. tak:
  1. throw new MySQLiQueryManagerException('Błąd połączenia z baza danych: ' . mysqli_connect_error());

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.