Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][MVC] Od czego zacząć?
Forum PHP.pl > Forum > PHP > Object-oriented programming
dragoste
Witam

W końcu skusiłem napisać smile.gif

Niedawno w poszukiwaniu jakiejś teorii pozwalającej oddzielić logikę od widoku itd trafiłem na MVC. Poczytałem, wszystko ok, rozumiem, tylko problem pojawia się przy chęci sprawdzenia teorii w praktyce.
MVC zakłada wyraźny podział na warstwy, które ze sobą współpracują i żadna sama w sobie dużo nie zdziała. Stąd moje pytania.
1.Od czego zacząć pisać, lub też najpierw projektować?

Klasy powinny pozwalać na przeniesienie ich do innych skryptów, w takim razie (2)jak na przykład pobierać dane z bazy danych jeśli do obsługi MySQL mam osobną klasę?

To na razie tyle. smile.gif
Sedziwoj
Po pierwsze skorzystaj z wyszukiwarki (ba na tej stronie jest co najmniej jeden temat o MVC).
dragoste
Czy wszystkie Twoje 418 postów tak wygląda? Czytając niektóre Twoje ostatnie posty tak sądzę.
Czy Ty na prawdę myślisz, że nie szukałem, nie czytałem? Więc uświadamiam Cię, że szukałem i czytałem. Połowa z nich dotyczy rozumienia pojęcia MVC, a druga połowa konkretnych problemów.

Ja natomiast pytam, od czego ( której warstwy ) i mniej więcej jak zacząć projektować coś takiego. Jeśli znajdziesz temat z konkretną odpowiedzią na moje pytania przyznam Ci rację.
em1X
np stworz sobie klasę bazową którą każda klasa będzie rozszerzać.
U mnie jest to np. klasa abstrakcyjna DocumentObject, która udostępnia połączenie z bazą itp.

  1. <?php
  2. abstract class DocumentObject {
  3.  
  4.  protected function getDatabase() {
  5. // dostęp do bazy danych
  6.  }
  7.  
  8.  protected function getRegistry() {
  9. // dostęp do rejestru (ustawień)
  10.  }
  11.  
  12.  // i tak dalej...  
  13. }
  14. ?>


następnie będzie inna klasa, np. AbstractView, ona rozszerza DocumentObject, do tego definiuje abstrakcyjne metody dla widoków, udostępnia smarty, i tak dalej.. warstwa po warstwie.. polecam przelecieć parę artykułów o MVC (ze zrozumieniem), potem brać się za robotę.
NuLL
Cytat(dragoste @ 15.10.2007, 15:21:21 ) *
Czy wszystkie Twoje 418 postów tak wygląda? Czytając niektóre Twoje ostatnie posty tak sądzę.
Czy Ty na prawdę myślisz, że nie szukałem, nie czytałem? Więc uświadamiam Cię, że szukałem i czytałem. Połowa z nich dotyczy rozumienia pojęcia MVC, a druga połowa konkretnych problemów.

Ja natomiast pytam, od czego ( której warstwy ) i mniej więcej jak zacząć projektować coś takiego. Jeśli znajdziesz temat z konkretną odpowiedzią na moje pytania przyznam Ci rację.

Odpowiedz na te wszystkie pytania sa na forum...
matix
Może na początek podkreślę - każdy programista ma inną wizję MVC - to tylko zwykły szablon. To tak jak szablon strony (załózmy z webmark-a, którą dobrze wspominam, niestety - już jej nie ma ;() każdy sobie to lekko przerobi, zmieni, itp. To tak gwoli ścisłości, gdyż to co niżej przedstawię, jednemu się będzie podobało, a drugiemu nie.

Przede wszystkim Kontroller ma zarządzać widokiem i modelem i nic nie wiedzieć o danych. To więc:

  1. <?
  2. class news {
  3.  
  4. public function pokaz()
  5. {
  6. $oView = new Widok; // wybieramy widok
  7.  
  8. // teraz przypisujemy kilka zmiennych, załóżmy tytuł i content strony.
  9. $oView -> title = 'To jest tytul strony';
  10. $oView -> aNews = $oView -> model -> PobierzNewsy();
  11.  
  12. // zwracasz widok
  13. return $oView -> index();
  14. }
  15. }
  16. ?>


Teraz pewnie wiele osób się zapyta, dlaczego to Widok przechowuje w swojej zmiennej instancję klasy Model ? Ano dlatego, żeby w widoku także można było pobierać dane z modelu, gdyż to jest założeniem MVC. Przy okazji jest to wiele wygodniejsze, gdyż jak jest np. lewe menu, które posiada np. blok "losowa fotka", to potem trzeba w każdej metodzie controllera dopisywac te bzdetne linijki kodu, by pobierane były dane z modelu. A po co , skoro można to zrobić jednym zapytaniem w Widoku.

Widok ma za zadanie gromadzić dane z szablonow i je zwracać controllerowi, tak więc (pomijam tutaj klasy abstrakcyjne, zeby pokazac oco chodzi - wiadomo - lepiej dziedziczyc sobie niektore metody z klasy abstrakcjii)

  1. <?php
  2. class Widok {
  3.  
  4. public function index()
  5. {
  6. $sPage = $this->display('header');
  7. $sPage .= $this->display('costam');
  8.  
  9. return $sPage;
  10. }
  11.  
  12.  
  13. public function display($sWhat)
  14. {
  15.  ob_start();
  16. include ($sWhat);
  17. $sContent = ob_get_clean();
  18.  
  19. return $sContent;
  20. }
  21.  
  22. public function __construct()
  23. {
  24. $this -> model = new Model;
  25. }
  26. }
  27. ?>


Model ma pobierać dane z różnych źródeł i je zwracać, czyli po prostu:

  1. <?
  2. Class Model {
  3.  
  4. public function PobierzNewsy () {
  5. $oDb = new Database('plik.ini'); // pobiera konfiguracje z pliku ini , np
  6. $oDb -> execute ('select * from news');
  7. return $oDb -> fetchData();
  8. }
  9. }
  10. ?>


Do tego dochodzi jeszcze FrontController który pobiera sobie z routera kontroller i akcję i odpala odpowiedni kontroller i jego metodę. W moim przypadku (czyt. moj fw) jest coś takiego, że FrontController wybiera kontroller, i później jest coś takiego:

  1. <?
  2. function execute()
  3. {
  4. $sController = $this -> oRouter -> getController();
  5. $sAction = $this -> oRouter -> getAction();
  6.  
  7. $oController = new $sController;
  8. echo $oController -> {$sAction} ();
  9. }
  10. ?>


i już wszystko jasne smile.gif

Mam nadzieję, że ten post rozwiąże wszelkie wątpliwości co i jak połączyć.

Pozdrawiam,
Matix.
dragoste
Dzięki za odpowiedzi smile.gif

Ale jednak jeszcze jedna sprawa. Jeśli chodzi o połączenie z DB. em1X podał klasę abstrakcyjną która zawiera metodę połączenia, i jest rozszerzana, przez resztę klas. Natomiast matix najwyraźniej ma osobną klasę Database, z której korzysta wewnątrz klas widoku. I właśnie o to pytałem też w pierwszym poście. Jeśli dobrze zrozumiałem, to wyszły dwa rozwiązania. Pierwsze, dzięki której jakby nie mieszamy klas. I drugie, czyli tak jak robiłem dotychczas, osobna klasa dla db i inne klasy wewnątrz tworzą jej obiekty.
Czy jakiś komentarz do tego, czy mam dobrze rozumiem, że przedstawiliście dwa sposoby i mam robić jak uważam ? smile.gif

matix'owi dziękuję za pokazanie relacji między warstwami, oraz matix'owi i em1X za podpowiedź do głównego pytania - od czego zacząć pisać. smile.gif

Aha i jeszcze jedno, do której warstwy zaliczamy tą klasę, którą podał em1X, model, czy kontroler.
matix
Tak jak pisałem. Jest to kwestia, jak kto woli.

Co do tego, gdzie ta klasa abstrakcyjna pasuje - stawiam na Model, gdyż połączenie z bazą oraz pobieranie configa do czegoś, jest raczej funkcją modelu. Chociaż szczeże nie widzę w tym sensu - po co wszystko ładować na raz do pliku. Lepiej wybierać to, co potrzebujesz. Jestem za swoją wersją winksmiley.jpg
dragoste
Ok, prawie mnie przekonałeś. winksmiley.jpg
Tylko jeszcze jedna sprawa. Patrząc na klasę Model, tworzy ona instancję klasy Database, oraz używa metod w niej zawartych. Co oznacza, że w innych klasach też by tak to miało wyglądać. W takim układzie jak radzić sobie w sytuacji, gdy chcę np. rozbudować, czy zmienić tę klasę ( Database). Dajmy na to zamiast metody wykonywującej zapytania dam kilka metod osobno od select, insert itd. ( przykład niekoniecznie sensowny smile.gif ) W tym przypadku zmieniałbyś we wszystkich klasach używających połączenia z DB metod?
matix
Tak, musisz zawsze zmienić w każdej metodzie modelu wszystko. Najlepiej weź kartkę, rozpisz sobie co i jak ma wyglądać i po prostu zrób jeden, porządny sterownik MySQL. Do przykładu, ja ci pokażę mój:

Klasę mojego autorstwa, db_mysql znajdziesz tutaj: http://cpaste.com/3175. Uploaded specjalnie for you smile.gif
Z kolei klasa db_abstract jest na stronie http://cpaste.com/3174.

Przykłady użycia:

  1. <?
  2. $oDb = new db_mysql;
  3. $oDb -> setSource('db');
  4.  
  5. $aZmien = array(
  6. 'title' => 'nowy tytul',
  7. 'content' => 'nowa tresc'
  8. );
  9.  
  10. $oDb -> setWhere('id = 5'); // odpowiednik zapytania select * from X where id = 5;
  11. $oDb -> setOrder('id desc');
  12. $oDb -> setLimit (0,5);
  13.  
  14. $oDb -> dbUpdate('ksiega', $aZmien);
  15. $oDb -> dbInsert('ksiega', $aZmien);
  16. $oDb -> dbDelete('ksiega');
  17.  
  18. print_r($oDb->dbSelect('ksiega', array('title', 'content')));
  19. ?>


Oczywiście z tej klasy możesz sobie skorzystać. Bardzo fajnie działa winksmiley.jpg

Pozdro tongue.gif
dragoste
1. Gdzie połączenie z DB? ;> Przegapiłem, czy brak? ( metoda dbConnect)
2. Podoba mi się biggrin.gif Miałem jeszcze kilka pytań ale już doszedłem wszystko co i jak działa w Twojej klasie zanim sformułowałem pytania biggrin.gif

Czyli jedyne pytanie to czy po prostu zapomniałeś połączyć się z bazę w przykładzie czy coś pominąłem snitch.gif

Skoro mówisz, że mogę skorzystać, to skorzystam smile.gif No może lekko przerobię.
matix
Nie, nie winksmiley.jpg Nic nie pominąłem.

Metoda dbConnect() jest odpowiedzialna za łączenie z bazą danych, tylko, że wyciąga ona dane z array-a w postaci:

  1. <?php
  2. $db = array (
  3. 'host' => 'localhost',
  4. 'user' => 'user',
  5. 'pass' => 'haslo',
  6. 'type' => 'mysql', // takie dla pdo ;)
  7. 'table' => 'tabela'
  8. );
  9. ?>


Natomiast jest takie cudo, jak setSource(), która pobiera mi przez mój frameworkowy config, plik /configs/nazwaconfiga.ini, gdzie jest konfiguracja w stylu

Kod
host = localhost
user = user
pass = pass
type = mysql
table = tabela


i wiadomo, przekształca to na arraya;)

Tak własnie to wszystko działa tongue.gif
Kiler
Cytat(matix @ 15.10.2007, 22:08:52 ) *
Tak, musisz zawsze zmienić w każdej metodzie modelu wszystko. Najlepiej weź kartkę, rozpisz sobie co i jak ma wyglądać i po prostu zrób jeden, porządny sterownik MySQL. Do przykładu, ja ci pokażę mój:

Klasę mojego autorstwa, db_mysql znajdziesz tutaj: http://cpaste.com/3175. Uploaded specjalnie for you smile.gif
Z kolei klasa db_abstract jest na stronie http://cpaste.com/3174.


witajcie,
A jak wygląda klasa db_exception questionmark.gif bo z kolei ja to przegapiłem gdzies smile.gif

pozdr
matix
  1. <?php
  2. class db_exception extends exception {}
  3. ?>


Tylko tyle;)
kruk
Cytat(matix @ 15.10.2007, 22:08:52 ) *
(...)
Klasę mojego autorstwa, db_mysql znajdziesz tutaj: http://cpaste.com/3175. Uploaded specjalnie for you smile.gif
Z kolei klasa db_abstract jest na stronie http://cpaste.com/3174.
(...)


Czy ktoś ma jeszcze aktualne kody tej klasy, zaprezentowanej przez matrix'a - Niestey powyższe linki są już nie aktualne :/
Będę wdzięczny uaktualnienie linków lub inne propozycje (niezbyt rozdętych) klas, tego typu
iro88
Aby nie tworzyć nowego tematu i nieco odświeżyć...

Jest w php kilka kwestii, które mnie nurtują. Mianowicie, chciałbym zrobić własny framework MVC, ponieważ wydaje mi się to prostsze niż korzystanie z istniejących 'kombajnów', zalewających człowieka na wstępie masą helperów. Zarazem chciałbym zrozumieć jak to wszystko działa i mieć to poczucie, że to co pisze jest w 100% napisane przeze mnie. To co obecnie zaplanowałem dla swojego frameworka MVC to struktura:

-Models
-Views
-Conrollers
index.php

(rewolucji nie ma ;P)


Aktualnie całość działa tak, indexController.php który przechwytuje zmienną z adresu ($strona=example), sprawdza ją pod kątem bezpieczeństwa i zwraca odpowiedni widok poprzez include do index.php

Widząc, frameworki innych osób, zastanawiam się, jak w to wszystko mam wpleść obiekty. Kombinowałem i jedyne do czego mi się przydadzą to modele danych, ale w innych wypadkach zastanawiam się po co? Skoro można zastosować funkcje? Z drugiej strony, widzę, że include niemal nie występuje w innych projektach, więc jak to jest?

Przyznam że, martwi mnie moje nadużywanie include. Do każdego widoku dołączam plik z modelem i plik z konrtollerem, a główny szablon już całkowicie jest naszpikowany tymi wszystkimi plikami. Czy moje obawy są słuszne? Czy da się to jakoś rozwiązać? I do czego mogą mi się tu przydać obiekty? Jak z nich korzystać?

Wiem, że pytania wydać się mogą śmieszne i może proste, ale nie mam kogo o to spytać.
cojack
Nie skupiaj się na implementacji, tylko na tworzeniu interfejsów. Zrozum czym jest programowanie zorientowane obiektowo.
Spawnm
Po ostatnim poście stwierdzam że iro88 nie zna podstaw oop a chce się brać za pisanie fw.
Iro88, naucz się dobrze php i jakiś fw i dopiero potem zabieraj się za własny jeśli nadal będziesz mieć taką potrzebę.
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.