Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wywołanie klasy z funkcji - czy to możliwe?
Forum PHP.pl > Forum > PHP
tikky
Witam,

Projektuję pewną aplikację w PHP/MySQL.
Od razu dodam, że nie jestem ekspertem, robię to na własne potrzeby i do obiektówki jeszcze nie dojrzałem.
Ogólnie wszystko działa jak trzeba ale robi mi się trochę bałagan w kodzie - miesza się HTML z PHP.

Wiem, że dobrą metodą jest oddzielenie warstwy wyświetlania, od kodu PHP ale nie bardzo wiem jak to zrobić.

I teraz aby sobie troche posprzątać, kod chciałem pewne rzeczy pochować do poszczególnych funkcji.
Problem mam wtedy gdy dana funkcja ma się łączyć z MySQL i pobierać jakieś dane.
Do połącznia z bazą używam klasy EZ_SQL (http://justinvincent.com/ezsql) i pojawiają mi się błędy gdy chcę
w środku mojej funkcji łączyć się z bazą za pośrednictwem klasy EZ_SQL. Czy to w ogóle możliwe?
Jak mogę to przeskoczyć? Jak to ułatwić, posprzątać?


Wiem, że najlepiej byłoby zrobić całóść w modelu MVC, mieć kontrolery, szablony itp. ale tak jak wspomniałem nie jestem programistą i na razie nie mam możliwości przerabiać wszystkiego od nowa.

Co mógłbym zrobić z kodem aby ułatwić sobie pracę i mieć porządek na etapie już istniejącego kodu?
nospor
To moze bys pokazal jak probujesz sie laczyc oraz jakei to bledy..... wrozbita pietro wyzej.
tikky
Nospor, oczywiście już uściślam:

Poniżej przykład fragmentu kodu, który na stronie wyświetla dane z bazy.
  1. $db->get_results("SET NAMES 'utf8'");
  2. $produkcja = $db->get_results("SELECT * FROM tab_zamowienia WHERE id_statusu BETWEEN '20' AND '70' ORDER BY id_zamowienia");
  3. echo '<h3 class="content-subhead"><i class="fa fa-building-o"></i> Zamówienia bieżące w produkcji</h3>
  4. <table>
  5. <thead>
  6. <tr>
  7. <th>ID <i class="fa fa-sort"></i></th>
  8. <th>Osoba <i class="fa fa-sort"></i></th>
  9. <th>Klient <i class="fa fa-sort"></i></th>
  10. <th>Status <i class="fa fa-sort"></i></th>
  11. </tr>
  12. </thead>';
  13. foreach ( $produkcja as $zamowienie )
  14. {
  15. echo "<tr>
  16. <td>".$zamowienie->id_zamowienia."</td>
  17. <td>".$zamowienie->osoba."</td>
  18. <td>".$zamowienie->klient."</td>
  19. <td>".$zamowienie->status."</td>
  20. </tr>";
  21. }
  22. echo "</table>";


Ponieważ używam tej tabeli kilka razy chciałem przenieść ten fragment do funkcji typu:
  1. function wyswietl_tabele(){
  2. $db->get_results("SET NAMES 'utf8'");
  3. $produkcja = $db->get_results("SELECT * FROM tab_zamowienia WHERE id_statusu BETWEEN '20' AND '70' ORDER BY id_zamowienia");
  4. echo '<h3 class="content-subhead"><i class="fa fa-building-o"></i> Zamówienia bieżące w produkcji</h3>
  5. <table>
  6. <thead>
  7. <tr>
  8. <th>ID <i class="fa fa-sort"></i></th>
  9. <th>Osoba <i class="fa fa-sort"></i></th>
  10. <th>Klient <i class="fa fa-sort"></i></th>
  11. <th>Status <i class="fa fa-sort"></i></th>
  12. </tr>
  13. </thead>';
  14. foreach ( $produkcja as $zamowienie )
  15. {
  16. echo "<tr>
  17. <td>".$zamowienie->id_zamowienia."</td>
  18. <td>".$zamowienie->osoba."</td>
  19. <td>".$zamowienie->klient."</td>
  20. <td>".$zamowienie->status."</td>
  21. </tr>";
  22. }
  23. echo "</table>";
  24. }



... i na głównej stronie wywoływać tylko kilka razy tę samą funkcję.
Niestety ten sposób nie działa, bo nie mogę wywołać klasy EZ_AQL wewnątrz funkcji, czyli "$db->get_results"
Jeśli coś jeszcze nie jasne proszę o informacje.
nospor
Zmienna $db nie jest widoczna w funkcji....

1) Poczytaj w manualu o zasiegu zmiennych
2) ALbo przekazuj do funkcji jako parametr te $db
3) Albo przeczytaj to
http://forum.php.pl/index.php?showtopic=227036&hl=new+T1
tu masz napisane jak przekazywac obiekt bazy do klas. Posrednio niektore metody z tamtego tematu dotycza i ciebie
tikky
NOSPOR: dzięki za odpowiedzi i porady.

Stworzyłem coś mi działa.
Jako, że jest to mój pierwszy kod w obiektówce, mam prośbę abyś rzucił tylko okiem czy to co napisałem jest zgodne z zasadą.

  1. <?php
  2. class Test extends db {
  3. public $imie = 'imie jeszcze nie pobrane';
  4.  
  5. public function __construct($id)
  6. {
  7. echo 'Jestem konstruktorem</br>';
  8. $db = new db(EZSQL_DB_USER, EZSQL_DB_PASSWORD, EZSQL_DB_NAME, EZSQL_DB_HOST);
  9. $zapytanie = $db->get_row("SELECT imienazwisko FROM tab_uzytkownicy WHERE id_uzytkownika=$id");
  10. $this->imie = $zapytanie->imienazwisko;
  11. }
  12.  
  13. function set_owner ($name) {
  14. $this->owner = $name;
  15. $zapytanie = $db->get_results("SELECT id_uzytkownika, imienazwisko FROM tab_uzytkownicy");
  16. $this->owner = $zapytanie->imienazwisko;
  17. }
  18. }
  19.  
  20.  
  21. //tworzymy nową instancję podając id intersującego nas użytkownika
  22. $osobnik = new Test(30);
  23.  
  24. //wyświetlamy imię z bazy - pobrane w konstruktorze klasy
  25. echo $osobnik->imie;
  26.  
  27. ?>
nospor
zle. W linku co ci podalem masz jasno napisane ze:
1) Nie dziedziczy sie po klasie DB
2) Nie tworzy sie w klasie wlasnych obiektow DB
tikky
Rozumiem to co piszesz, ale nie bardzo wiem jak to przerobić żeby było zgodnie ze sztuką.

Czy to oznacza, że w moich klasach w ogóle nie powinienem używać EZ_SQL?
Do tej pory używałem go gdyż jest dla mnie bardzo wygodny i popularnie stosowany (np. WordPress go używa).

Czy mógłbyś mi jakiś przykład dać jak to powinienem zrobić, bez dziedziczenia db?
Chciałbym przejść z pisania strukturalnego na obiektowe, ale wolałbym wiedzieć jak zrobić porządnie chociaż proste
rzeczy - takie właśnie jak połączenie z bazą i wyciągnięcie danych.
nospor
Oczywiscie ze masz uzywac obiektu DB. ALe masz go do klasy przekazywac z zewnatrz.
tikky
Nospor: ok, chyba rozumiem.
Nie chcę iść na łatwiznę - próbuję coś sam zrobić ale idzie jak po gruzie.
Przsepisałem to mając na uwadze to co piszesz:

  1. <?php
  2. // dodaję klasę EZ_SQL
  3. include_once "ez_sql.php";
  4.  
  5. //gdzieś tam w aplikacji tworzę sobie taki obiekt
  6. $db = new db(EZSQL_DB_USER, EZSQL_DB_PASSWORD, EZSQL_DB_NAME, EZSQL_DB_HOST);
  7.  
  8. //dalej klasa bez dziedziczenia db
  9. class Test2 {
  10. public $imie = 'imie jeszcze nie pobrane';
  11.  
  12. public function __construct($db, $id)
  13. {
  14. echo 'Jestem konstruktorem klasy Test2</br>';
  15. $zapytanie = $db->get_row("SELECT imienazwisko FROM tab_uzytkownicy WHERE id_uzytkownika=$id");
  16. $this->imie = $zapytanie->imienazwisko;
  17. }
  18. }
  19.  
  20.  
  21. //tworzymy nową instancję podając id intersującego nas użytkownika
  22. $osobnik = new Test2($db, 30);
  23. //wyświetlamy imię z bazy - pobrane w konstruktorze klasy
  24. echo $osobnik->imie;
  25.  
  26. ?>



Czy teraz dobrze? Lepiej?
Jeśli nie to prośba o pomoc, konkretny kod który by działał i był zgodny z zasadami.
nospor
Tak, teraz lepiej smile.gif
Ale skoro przekazujesz $db do konstruktora, to dobrze by bylo bys to $db zapamietal jako wlasciwosc klasy i mogl przez $this sie do niej wszedzie odwolywac.
tikky
Nospor,

Wgryzam się powoli w temat OOP, ale idzie mi to opornie.

Masz racje, fajnie byłoby zapamiętać własciwości ale nie wiem jak to zrobić. Czy mogę prosić Cię o modyfikację mojego kodu?
nospor
Wlasciwosci klasy to sa podstawy klas i obiektow. W manualu php jest dział na temat klas i tam te wszystkie podstawy są wyjasnione.
tikky
Nospor: Wracam do tematu programowania obiektowego i pozwolę sobie wrócić do pytania.
Czy poniższy rodzaj programowania i łączenia z bazą jest ok:

  1. //dołączenie pliku z klasą do połączenia z bazą - EZ_SQL
  2. include 'ez_sql.php';
  3.  
  4. class Klienci
  5. {
  6.  
  7. public function __construct()
  8. {
  9. //tworzę jeden obiekt do połączenia z bazą
  10. $db = new db(EZSQL_DB_USER, EZSQL_DB_PASSWORD, EZSQL_DB_NAME, EZSQL_DB_HOST);
  11. $this->baza = $db;
  12. }
  13.  
  14. function podajImie($id)
  15. {
  16. //tu już nie tworzę nowe połączenia tylko odnoszę się do istniejącego
  17. $db = $this->baza;
  18. $zapytanie = $db->get_row("SELECT imienazwisko FROM tab_uzytkownicy WHERE id_uzytkownika=$id");
  19. if($zapytanie==TRUE)
  20. $this->imie = $zapytanie->imienazwisko;
  21. else
  22. echo 'Błąd: nie ma usera o tym ID -';
  23. }
  24.  
  25. function podajFirme($id)
  26. {
  27. $db = $this->baza;
  28. $zapytanie = $db->get_row("SELECT id_firmy FROM tab_uzytkownicy WHERE id_uzytkownika=$id");
  29. echo $zapytanie->id_firmy;
  30. }
  31.  
  32. function dodajEmail($adres_email, $id)
  33. {
  34. $db = $this->baza;
  35. $zapytanie = $db->query("UPDATE tab_uzytkownicy SET mail = '$adres_email' WHERE id_uzytkownika=$id");
  36. echo 'dodano email';
  37. }
  38.  
  39. function ileKlientow()
  40. {
  41. $db = $this->baza;
  42. $ilosc = $db->get_var("SELECT count(*) FROM tab_uzytkownicy");
  43. echo "<br>W bazie jest: ".$ilosc." klientów";
  44. }
  45.  
  46. }
  47.  
  48. $osobnik = new Klienci;
  49. print($osobnik->podajImie(99));
  50. print($osobnik->podajFirme(30));
  51. $osobnik->dodajEmail("adres@serwer.pl", 23);
  52. $osobnik->ileKlientow();
nospor
1) Obiekt klasy bazy danych nie powinien byc tworzony w klasie klienta. Obiekt ten, ma byc tworzony oddzielnie i przekazywany do klasy klienta
2) Klasa nie powinna pluc ECHem wiadomosci. Klasa najlepiej powinna rzucac wyjątkami, gdy coś pojdzie nie tak
3) Bez sensu jest tworzyc metody podajImie, podajFirme... gdy bedziesz chcial pobrac dane danego usera, to bedziesz musial wywolan x takich metod, a kazda na dodatek leci z zapytaniem do bazy. Ma byc jedna metoda: podajKlienta i ona zwroci tablice danego usera
A juz w ogole najlepiej pownna byc klasa Klient, ktora by miala wlasciwosci takie jakie tabela Klienta.
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.