Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> [MVC] Moj poczatek / implementacja
Helios
post
Post #1





Grupa: Zarejestrowani
Postów: 24
Pomógł: 0
Dołączył: 8.07.2006

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


Witam
Od niedawna zaczalem interesowac sie MVC. Ale w dalszym ciagu nie wiem czy dobrze rozumuje istote MVC. Dlatego postanowilem napisac prosty (powtarzam, prosty, system) zeby sprawdzic czy ide w dobrym kierunku. Prosze o komentarze, jesli chodzi o sam schemat i istote wzorca MVC.

Na poczatek przedstawie strukture katalogow:

./ - katalog glowny
actions/ - katalog przechowujacy pliki .ini do wybranej akcji mozemy podac co ma zostac wykonane nastepnie
configs/ - katalog z plikami konfiguracyjnymi - narazie nie uzyty
controllers/ - katalog z kontrolerami - narazie tylko kontroler glowny
models/ - katalog z plikami modeli
views/ - katalog z plikami widokow
index.php - plik glowny ktory uruchamia kontroler

Zaczynamy od poczatku - kod kontrolera:
  1. <?php
  2.  
  3. class Ctrl{
  4.  
  5. private $Request=false; // obiekt
  6. private $action; // nazwa akcji - nieobowiazkowa
  7. private $view; // nazwa widoku
  8. protected $model; // nazwa modelu - nieobowiazkowa
  9.  
  10. protected $objView; // obiekt widoku
  11. protected $objModel; // obiekt modelu
  12.  
  13. // konstruktor
  14. public function __construct($request){ 
  15.  
  16. // ustawianie pol klasy
  17. $this->view=$request->getParam('view');
  18. $this->view=($this->view) ? $this->view : 'main'; // ustawianie standardowego widoku
  19. // jesli zostal podany model ustawia jesli nie jest taki sam jak nazwa widoku
  20. $this->model=($request->getParam('model')) ? $request->getParam('model') : $this->view;
  21. // model z sufixem Mod
  22. $this->model.='Mod';
  23. // pobiera parametr akcji o ile zostal podany
  24. $this->action=$request->getParam('action');
  25.  
  26. // jesli zostala podana akcja laduje model i wykonuje odpowiednia czynnosc
  27. if($this->action){
  28. require_once('./models/'.$this->model.'.model.php');
  29. $this->objModel=new $this->model($request);
  30. $action=$this->action;
  31. $this->objModel->$action();
  32. do{
  33. // sprawdza czy plik konfiguracyjny akcji uwzglednia wykonanie kolejnej akcji
  34. $tmpCfg=parse_ini_file('./actions/'.$this->action.'.ini');
  35. $action=$tmpCfg['next'];
  36. // jesli tak to ja wykonuje itd.
  37. $this->objModel->$action();
  38. }while(!$tmpCfg['next']);
  39. }
  40. // laduje obiekt widoku
  41. $this->execute();
  42. }
  43.  
  44. public function execute($view=false){
  45. // sprawdza czy obiekt modelu juz istnieje czyli czy podana byla akcja
  46. if(!is_object($this->objModel)){
  47. require_once('./models/'.$this->model.'.model.php');
  48. $this->objModel=new $this->model($request);
  49. }
  50. // laduje obiekt widoku
  51. require_once('./views/'.$this->view.'.view.php');
  52. $this->objView=new $this->view($this->objModel);
  53. }
  54.  
  55. }
  56.  
  57. ?>

Zakladamy, ze uzytkownik wpisal: index.php?view=Users&action=addUser&userName=root
kontroler laduje wiec model UsersMod:
  1. <?php
  2.  
  3. class UsersMod {
  4.  
  5. public $addedUser;
  6. public $request;
  7. public $count;
  8.  
  9. function __construct($request){
  10. $this->request=$request;
  11. }
  12.  
  13. function addUser(){
  14. $this->addedUser=$this->request->getParam('userName');
  15. return true;
  16. }
  17.  
  18. function countUsers(){
  19. return $this->count++;
  20. }
  21.  
  22. function getAddedUser(){
  23. return $this->addedUser;
  24. }
  25.  
  26. function getUsersNum(){
  27. return $this->count;
  28. }
  29.  
  30. }
  31.  
  32. ?>

i wykonuje w nim akcje zmianu danych, a poniewaz akcja addUser() posiada plik konfiguracjny z wywolaniem jako kolejnej akcji countUsers wywoluje kolejna akcje. No i pozostaje wyswietlenie widoku Users:
  1. <?php
  2.  
  3. class Users {
  4.  
  5. function __construct($objModel){
  6. print 'Dodalem uzytkownika: '.$objModel->getAddedUser().' i teraz mam zarejestrowanych uzytkownikow: '.$objModel->getUsersNum();
  7. }
  8.  
  9. }
  10.  
  11. ?>


Co sadzicie o tym? Czy dobrze rozumuje istote MVC? Zapraszam do dyskusji...
Go to the top of the page
+Quote Post
hwao
post
Post #2


Developer


Grupa: Moderatorzy
Postów: 2 844
Pomógł: 20
Dołączył: 25.11.2003
Skąd: Olkusz




Jeżeli to działą, to jest dobre... Nie ma "szablonowej" implementacji tego wzorca w zadnym z jezyków, dla tego trzeba tylko znac załozenia i tworzyc własne.

Tutaj masz opis wzorca, nie implementacji:
http://hwao.be/blog/2006/04/14/model-view-controller/

Raczej jak sa katalogi, to najmniej wazne poniewaz powinny byc ustawione przez stale (przynajmniej ja tak robie).

Troche wydaje mi sie dziwny ten kontroler, poniewaz jest jakis taki "malo" elastyczny. Napisz pare aplikacji na tym to Ci zaraz przyjdzie do glowy jakies lepsze rozwiazanie.

Umnie widok robi troche inna rzeczy, a to co jest u Ciebie, u mnie robi to system szablonów.
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #3





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Cóż. To zależy, czy widok ma wyciągac dane, czy aplikacja te dane wstawiać smile.gif Niby różnica niewielka w praktyce, ale w podejściu do problemu ogromna :|


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
ActivePlayer
post
Post #4





Grupa: Przyjaciele php.pl
Postów: 1 224
Pomógł: 40
Dołączył: 6.07.2004
Skąd: Wuppertal

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


@hwao co widok robi u CIebie ?
Go to the top of the page
+Quote Post
hwao
post
Post #5


Developer


Grupa: Moderatorzy
Postów: 2 844
Pomógł: 20
Dołączył: 25.11.2003
Skąd: Olkusz




Cytat(Cysiaczek @ 8.07.2006, 22:58 ) *
Cóż. To zależy, czy widok ma wyciągac dane, czy aplikacja te dane wstawiać smile.gif Niby różnica niewielka w praktyce, ale w podejściu do problemu ogromna :|

Widok, wyciagac dane?! Widok ma inne zadania! To model jest warstwa ktora powinna pozyskiwac dane, z różnych źródeł! Podsumowujac, widok otrzymuje gotowe dane z modelu i zajmuje sie obrobka ich (prezentacja uzytkonikowi), model zajmuje sie wyciaganiem danych.
Cytat(ActivePlayer @ 8.07.2006, 23:34 ) *
@hwao co widok robi u CIebie ?

Umnie głównym zadaniem widoku jest pozyskanie danych przez(od) modelu i poprzez system szablonów przedstawienie ich użytkownikowi.
Go to the top of the page
+Quote Post
ActivePlayer
post
Post #6





Grupa: Przyjaciele php.pl
Postów: 1 224
Pomógł: 40
Dołączył: 6.07.2004
Skąd: Wuppertal

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


u mnie element widok to 'class view extends smarty'...
w akcji pobieram poprzez model dane, assign do widoku, i display.
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #7





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Cytat(hwao @ 8.07.2006, 21:49 ) *
Umnie głównym zadaniem widoku jest pozyskanie danych przez(od) modelu i poprzez system szablonów przedstawienie ich użytkownikowi.


O to mi chodziło - o pozyskanie danych. Inaczej - czy widok jest pasywny, czy aktywny. Nie chodziło o pozyskanie danych z bazy.

Ewentualne problemy z komunikacją wynikają z tego, że ja używam pojęcia <widok> na określenie szablonu/template'a/jakzwałtakzwał

Ten post edytował Cysiaczek 8.07.2006, 23:08:29


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
Ociu
post
Post #8





Grupa: Moderatorzy
Postów: 1 566
Pomógł: 37
Dołączył: 14.05.2003
Skąd: Kraków




Jak na pierwsze starcie nie jest najgorzej.
Jak pisał hwao, niezbyt elastyczne to jest.

Ja podzieliłem kontrolę na: Controller, webController -> FrontController, BlockController; ConsoleController.
Go to the top of the page
+Quote Post
Prph
post
Post #9





Grupa: Zarejestrowani
Postów: 338
Pomógł: 2
Dołączył: 4.03.2006
Skąd: Łódź

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


Witam,

Ostatnio napisalem (mam nadzieje) framework i z przyjemnoscia podziele sie moimi uwagami.

1. NAJWAZNIEJSZA ZASADA
Jezeli piszesz framework dla siebie - pisz go tak, aby byl wygodny dla Ciebie.

2. MVC
MVC mowi, ze masz miec model, widok i kontroler. Model nie wyswietla daych, widok nie grzebie w bazie. Kontroler umozliwia im jakas tam wspolprace.


Nie podoba mi sie struktura katalogow. Tzn ja zmianilbym ja na nastepujaca:

actions/ - kontrolery akcji
models/ - modele
views/ - widoki
configurations/ - konfiguracje wszystkiego co zbudujesz na owym frameworku (np. akcji lub bibliotek, ktore bys mogl pozniej dodac.)

konfiguracje mozesz zapisywac w plikach o przykladowych nazwach: DodajUzytkownikaAction.ini, UsunNewsaAction.ini, MojaBibliotekaJPEGLibrary.ini.

Teraz nieco do kontrolera. Ktos powiedzial, ze jest malo elastyny. No w sumie trudno go zrobic innego, jak kolega dopiero zaczyna.
Ja przyczepie sie do fragmentu nastepujacego:

  1. <?php
  2. if($this->action){
  3. require_once('./models/'.$this->model.'.model.php');
  4. $this->objModel=new $this->model($request);
  5. $action=$this->action;
  6. $this->objModel->$action();
  7. do{
  8. // sprawdza czy plik konfiguracyjny akcji uwzglednia wykonanie kolejnej akcji
  9. $tmpCfg=parse_ini_file('./actions/'.$this->action.'.ini');
  10. $action=$tmpCfg['next'];
  11. // jesli tak to ja wykonuje itd.
  12. $this->objModel->$action();
  13. }while(!$tmpCfg['next']);
  14. }
  15. // laduje obiekt widoku
  16. $this->execute();
  17. ?>


Dlaczego ladujesz model? To nie nalezy do kontrolera. Ja wiem, ze moze byc tak wygodnie. Ale sa akcje w ktorych z niego nie skorzystasz. Przyklad?

Akcja ktora wyswietla kominikat, jezeli nie znaleziono strony. Np masz akcje PokazZdjecia. Ktos wpisze adres:
jakasStrona.pl/akcja=PokazFotografie.

Jezeli kontroler nie znajdzie PokazFotografie to milo jest, jak odpalisz akcje np. NieZnaleziono. Ona wyswietli jedynie komunikat, zwroci Error 404 lub cos innego. Model nie jest tu najczesciej potrzebny.

Zrob tak:

1. Sprawdz o jaka akcje uzytkownik prosi. np: strona.pl/akcja=PokazZdjecie.
2. Jezeli jest pusta (np. podano strona.pl/), to ustaw domyslna (np. StronaGlowna).
3. Jezeli nie jest pusta, pobiez ja i sprawdz czy istnieje.
4. Jezeli nie, przypisz akcji akcje NieZnaleziono. Sprawdz czy istnieje (tak dla spokoju) i jak nie ma akcji (usunales ja, albu dysk padl winksmiley.jpg), to zglos jakis blad.

5. Jezeli akcja istanieje - uruchom ja.

Teraz akcja jezeli chce, prosi po model, ustawia sobie widok. Pobiera dane z modelu, przekazuje je widokowi. Widok moze wyswietlic, albo zwrocic kontrolerowi (w kontrolerze piszesz $oWidok = $oAkcja->uruchom()winksmiley.jpg. Wtedy kontroler ja wyswietla albo robi co mu sie podoba winksmiley.jpg

Zeby nie bylo malo, zalaczam fragmenty mojego kodu:
  1. <?php
  2. class Error403Action extends Action
  3. {
  4.  
  5. public function execute()
  6. {
  7. return Controller::getInstance()->getView('Error403'); // kontroleg glowny tworzy mi obiekt widoku o tej nazwie.
  8. }
  9. }
  10. ?>


  1. <?php
  2.  
  3. class Error403View extends ExtendedHtmlView
  4. {
  5. public function __construct()
  6. {
  7. parent::__construct(); // wywoluje konstruktor klasy bazowej. Raczej jest mi to potrzebne.
  8.  
  9. $this->setTemplate('Error403'); // ustawiam sobie szablon. Uzywam zwyklych szablonow php.
  10. }
  11. }
  12.  
  13. ?>


Dam jeszcze przyklad jak to jest z modelem:

  1. <?php
  2. class ShowPageAction extends Action
  3. {
  4. public function execute()
  5. {
  6. $oController = Controller::getInstance();
  7.  
  8. $sPageName = $oController->getContext()->getRequest()->getParameter('page', HttpRequest::GET);
  9.  
  10. if(is_null($sPageName))
  11. $sPageName = 'Index';
  12.  
  13. $oPageModel = $oController->getModel('Page');
  14.  
  15. if(!($aPage = $oPageModel->getPageByName($sPageName)))
  16. {
  17. $oController->forward(_ACTION_ERROR_404);
  18. return null;
  19. }
  20.  
  21. $oView = $oController->getView('ShowPage');
  22.  
  23. if(!empty($aPage['title']))
  24. $oView->setAttribute('pageTitle', $aPage['title']);
  25.  
  26. $oView->setAttribute('pageContent', $aPage['content']);
  27.  
  28. return $oView;
  29. }
  30.  
  31. public function isSecure()
  32. {
  33. return false;
  34. }
  35. }
  36. ?>


  1. <?php
  2. class PageModel
  3. {
  4. public function getPageByName($sPageName)
  5. {
  6. $sPageName = basename($sPageName);
  7.  
  8. $sPageFileName = _DIR_APPLICATION . 'pages/' . $sPageName . '.html';
  9.  
  10. if(is_readable($sPageFileName))
  11. {
  12. $aPage['title'] = null;
  13. $aPage['content'] = file_get_contents($sPageFileName);
  14.  
  15. return $aPage;
  16. }
  17. else
  18. return false;
  19. }
  20. }
  21. ?>


Mama nadzieje, ze troche pomoglem.

Adrian.
Go to the top of the page
+Quote Post
.rh-
post
Post #10





Grupa: Zarejestrowani
Postów: 50
Pomógł: 0
Dołączył: 16.07.2005

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


Witam

Odgrzebuje temat, podpisuje się pod nim. Również zaczynam swoja przygodę z tym zagadnieniem, a nie chce zaczynać nowego topiku.

@Prph
Odnośnie rozmieszczenia katalogów.
W swoim mini projekcie mam katalog moduły, w którym zawieram podział na np.:
News, Products itp. W każdym z tych katalogów mam widok np (news_view, czy products_view, model (w skład modelu wchodzą dwie klasy ) ( 1- model reprezentuje u mnie klasa która jest odzwierciedleniem pól/kolumn bazy danych, 2 – klasa ze statycznymi metodami do zapisywania aktualizowania i pobierania danych itp. ) Widok to klasa która zawiera metody odpowiedzialne za konkretna akcje np.:
  1. <?php
  2. public function buildMenuTable() {
  3.  $rs = MenuMapper::getAll();
  4.  $this->tpl->setVar('rs', $rs);
  5.  return $this->tpl->fetch('menuTable.tpl.php');
  6. }
  7. ?>

A w pliku menuTable.tpl.php prezentacja danych...

Do tego mam jeden kontroler ktory zczytuje z url odpowiednie akcje i includuje odpowiednie pliki.

Czy rozwiązanie które zaprezentowałem kwalifikuje się na mini MVC (wiem ze takie cos nie istnieje...) ? Czy w dobrym kierunku idę ?

Pozdrawiam
Go to the top of the page
+Quote Post
Ociu
post
Post #11





Grupa: Moderatorzy
Postów: 1 566
Pomógł: 37
Dołączył: 14.05.2003
Skąd: Kraków




W mvc chodzi o to, aby moduły/akcje były podzielone teoretycznie na kontroler akcji, widok akcji i model akcji. Jak sobie zimplementujesz to Twoja osobista sprawa.
Go to the top of the page
+Quote Post
Prph
post
Post #12





Grupa: Zarejestrowani
Postów: 338
Pomógł: 2
Dołączył: 4.03.2006
Skąd: Łódź

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


Ociu dobrze mowi smile.gif

Pamietaj, ze MVC to nie framework. MVC to tylko ideologia pisania aplikacji. Podam Ci zupelnie inny przyklad jego uzycia, a w pelni poprawny:

  1. <?php
  2. //index.php
  3. // Pokazuje dane o jakims uzytkowniku. Powiedzmy trzymane sa one w bazie.. no nie 
    wazne ;)
  4. // parametr id przekazywany jest w adresie.
  5.  
  6. $id = (int)$_GET['id'];
  7.  
  8. $oUzytkownik = new Uzytkownik($id);
  9. $sImieUzytkownika = $oUzytkoiwnik->getName(); 
  10.  
  11. $oSzablony = new Smarty(); // Przepraszam, ale dawno nie uzywalem smarty, nie wiem dokladnie jak go uzyc ;)
  12.  
  13. $oSzablony->assign('nazwa_uzytkownika', $sImieUzytkownika);
  14. $oSzablony->display('SzablonUzytownikow');
  15. ?>


  1. <!-- SzablonUzytkownikow.tpl -->
  2.  
  3. <h1>To strona o uzytkowniku</h1>
  4. <p>Uzytkownik ma na imie {$nazwa_uzytkownika}</p>


Nie ma zadnego frameworka, a jednak MVC. Uyztkownik jest modelem - zauwaz, ze powiedzialem, ze dane sa w bazie danych, ale jednak nie ma tu najmniejszego kodu, ktory na to wskazuje. Tak naprawde wie o tym tylko model. On sie laczy z baza danych (mysql, postrgesql, czy nawet plikami xml) i zwraca nam to, czygo szukamy.

Widok, to obiekt Smarty - systemow szablonow. Oczywiscie nikt nie kaze uzywac smarty (ja nie uzywam winksmiley.jpg).

Kontroler to index.php. Pobiera dane z $_GET, z modelu, przekazuje je do widoku i go wyswietla.

Adrian.
Go to the top of the page
+Quote Post
.rh-
post
Post #13





Grupa: Zarejestrowani
Postów: 50
Pomógł: 0
Dołączył: 16.07.2005

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


Zgadza sie, pytam, gdyz czytajac wiele artykulow w pewnym momencie nie wiedzialem za co sie zabrac, a bardzo mi zalezalo na tym aby moj kod php byl tak obiektowy jak kod java:) odstawilem wiec czytanie i zabralem sie za pisanie...

Wiec wnioskuje ze to co napisalem w poprzednim moim poscie mialo "jakis" sens skoro nie zostalem obrzucony i sprowadzony do parteru:). Super.

Pozdrawiam!
Go to the top of the page
+Quote Post
thornag
post
Post #14





Grupa: Zarejestrowani
Postów: 504
Pomógł: 2
Dołączył: 31.03.2006
Skąd: Londyn

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


Cytat(Helios @ 8.07.2006, 14:42 ) *
i wykonuje w nim akcje zmianu danych, a poniewaz akcja addUser() posiada plik konfiguracjny z wywolaniem jako kolejnej akcji countUsers wywoluje kolejna akcje. No i pozostaje wyswietlenie widoku


Pozwolilem sobie odgrzebac temat by zadac male pytanie. Ja postanowilem zaczac od czytania i zbierania wiedzy, ale wciaz jedna rzecz nie daje mi spokoju. Pliki akcji. Wszedzie gdzie czytam wyjasnione jest M V i C nie moge doczytac o akcjach. Z tego co jest podane wynika ze sa to jedne z najmniejszych niepodzielnych czynnosci, takie jak AddUser ModifyUser. Ok mozna przyjac ze akcja to wywolanie metody obiektu. Ale co z lancuchami i z plikami konfiguracyjnymi (z czego najbardziej nie zrozumiale sa dla mnie te drugie)? Co oznacza ze cos "posiada plik konfiguracjny z wywolaniem jako kolejnej akcji"

Bede wdzieczy za maly wyklad ewentualnie linki do zrodel gdzie bedzie to idiotoodpornie wytlumaczone.

Ten post edytował thornag 22.08.2006, 18:55:15


--------------------
"Wizja czasu jest szeroka, lecz kiedy sie przez nia przechodzi, czas staje sie waskimi drzwiami"

Go to the top of the page
+Quote Post
Prph
post
Post #15





Grupa: Zarejestrowani
Postów: 338
Pomógł: 2
Dołączył: 4.03.2006
Skąd: Łódź

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


Witam,

Akcja: dobrze rozumiesz czym jest. Akcja to po prostu realiacja jakiegos zadania. Np:
www.strona.pl?pokaz=galeria_fotografii. Z linku mozemy wywnioskowac, ze apliakcja php ma nam zaprezentowac galerie. To wlasnie galeria jest akcja. Tak samo moze byc akcja PokazNowosc, UsunUzytkownika.

Lancuchy akcji
Podczas jednego wywolania strony aplikacja php moze tak naprawde wykonac kilka kacji po kolei (czyli nastapi lancuch akcji). Jak? Oto przyklad:

Uzytkownik przeglada fotki na stronie. JEdna sie sie podoba, klika na UsunZdjecie.
Aplikacja php usuwa fotke z bazy lub z innego zrodla i powraca ponownie do wyswietlania fotek.
Jak to jest z poziomu aplikacji?

Zgloszenie: strona.pl/?akcja=UsunZdjecie&zdjecie=123.
Odczytuje id zdjecia (123), usuwa zdjecie
Uruchamia akcje PokazZdjecia. W efekcie uzytkownik odstaje fotki na ekranie, ale bez tej usunietej smile.gif.

To samo da sie realizowac przy pomocy redirect:

  1. <?php
  2. // plik z UsunZdjecie:
  3.  
  4. // usun z bazy fotke i wroc do prezentowania fotografii:
  5.  
  6. header('Location: <a href="http://strona.pl/?akcja=PokazZdjecia');" target="_blank">http://strona.pl/?akcja=PokazZdjecia');</a>
  7. exit;
  8. ?>


Zaleta lancucha akcji jest taka, ze strony nie trzeba przeladowac, wiec oszczedza sie czas smile.gif Efekt jest identyczny.

Konfiguracja i lancuchy akcji


Chyba chodzi o to, ze tworzony jest plik konfiguracyjny. znajduje sie w klatalogu configs/ i nazywa sie UsunZdjecie.php.

Aplikacja otrzymuje zgloszenie aby uruchimic akcje UsunZdjecie. Zna nazwe akcji i wie, ze tak samo ma nazywac sie konfig. Wiec wczytuje konfiga.

W konfigu moze byc podane: nastepna-akcja = 'PokazZdjecia'. Aplikacja wie, ze jak wykona akcje UsunZdjecie to ma wykonac PokazZdjecia.

UWAGA: to rozwiazanie jest raczej kiepskie. Lepiej w akcji zrobic metode "forward($nazwaAkcji, $parametry)" i po zakonczeniu danej akcji uruchamiac ja. CZesto zdarzy sie, ze bedziemy musieli wykonac inna akcje, bo nastapil jakis blad (np nie podano parametru id do usuniecia zdjecia.).

Pozdrawiam, Adrian.
Go to the top of the page
+Quote Post
thornag
post
Post #16





Grupa: Zarejestrowani
Postów: 504
Pomógł: 2
Dołączył: 31.03.2006
Skąd: Londyn

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


Tak to wszystko miele i mam jeszcze kilka kolejnych pytan. Realizacja rejestrowania uzytkownika w frameworku opartym o wzorzec MVC. Kompletnie nie wiem z ktorej strony to ugryzc.

Dla przykladu. Zostaje wywolany URL http://www.domena.pl/view=RegistrationForm

Kontroller laduje widok RegistrationForm, jako ze nie ma modelu ,kontroller laduje defaultowy model np index. W modelu index metoda np Perform jest pusta (musi zostac zaimplementowana gdyz chcialbym zeby model dziedziczyl po abstrakcyjnej klasie model).

Kontroller laduje model, wywoluje pusta metode Perform modelu - nic sie nie zmienia.
Kontroller wywoluje metode Display() - zostaje wyswietlony formularz rejestracyjny.

Uzytkownik wypelnia formularz i klika w wyslij (walidacja po stronie przegladarki juz byla). I tutaj zaczynaja sie moje problemy.

Jak to wyglada dalej ? Mam sobie obiekt Request i w nim moge przeprowadzic walidacje po stronie serwera.

Ale jak to polaczyc dalej ?

Akcja formularz powiedzmy wyglada tak. http://www.domena.pl/model=User&action=AddNewUser

Kontroller laduje model User, i chce uruchomic akcje AddNewUser, i co dalej ?Ciagle potrzebuje walidacji bo nie wiem gdzie ja tutaj wcisnac, potrzebuje akcje w stylu User->setUsername($username), User->setAddress($address) itp, kiedy przelece przez wszystkie setCostam (powiedzmy ze walidacje ustawie w tych metodach), teraz musze wywolac Model->SaveUser() co powoduje zapisanie ustawionych pol do bazy danych. I teraz znow nie wiem co dalej, w tej akcji ustawic kolejna ktora ustawi widok na np RegistrationDone ?

Same tutaj problemy, powiedzmy ze poczawszy od metody setUsername zawiera ona instrukcje zeby kolejna wywolac setEmail() ta znowu setAddress() itp. Ale co jesli bede chcial wykonac zwykla operacje zmiany Addressu, ktora normalnie wygladala by tak.

  1. <?php
  2. $user = New User($id) // nastepuje ladowanie danych do wlasciwosci.
  3. $user->setAddress($newAddress);
  4. $user->Save();
  5. ?>


Jak sterowac takim dzialaniem za pomoca URL ? Gdzie tu wszedzie jest klasa Request ktora w gruncie rzeczy powstala u mnie po to zeby zajmowac sie calym I/O walidacja eskejpowaniem cytowaniem itp.

Ogolnie jak mowie naczytalem sie sporo ale nie potrafie tego do kupy poskladac.

Ten przyklad obslugi uzytkownika nurtuje mnie najbardziej, stad tez mam prosbe.

Biorac pod uwage nastepujacy StoryBoard :

Kod
1. Uzytkownik wchodzi na strone. Klika w "zarejestruj sie". Wypelnia formularz. Formularz nie zawiera bledow, uzytkownik widzi podziekowania. Uzytkownik jest na stronie glownej (zalogowany). Klika w profil. Chce zmienic swoj adres.

2. Uzytkownik wchodzi na strone. Klika w "zarejestruj sie". Wypelnia formularz. Formularz zawiera bledy, uzytkownik zostaje przekierowany na strone formularza(nie chodzi tutaj o informowanie co zrobil zle). Wypelnia jeszcze raz


Co do mojej prosby, moglby mi ktos opisac jak takie cos zrealizowac ( nie chodzi mi o to zeby to ktos zaimplementowal smile.gif), ogolnie taki Walkthrough na zasadzie:

Uzytkownik jest na stornei glownej mamy URL kontroller robi to tamto. Pozniej jest na stronie ?view=form (czy cos) kontroller robi to i tamto.

Wielkie dzieki za zainteresowanie.

@Prph Raz jeszcze dzieki, w koncu lancuchy staly sie klarowne w teori smile.gif


--------------------
"Wizja czasu jest szeroka, lecz kiedy sie przez nia przechodzi, czas staje sie waskimi drzwiami"

Go to the top of the page
+Quote Post
Prph
post
Post #17





Grupa: Zarejestrowani
Postów: 338
Pomógł: 2
Dołączył: 4.03.2006
Skąd: Łódź

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


Witam,

Nie podoba mi sie u Ciebie organizacja MVC. Po pierwsze: strona.pl?model=Cos - zgloszenie moze zawierac jedynie akcje i parametry.

Uruchamiana jest akcja.
Akcja wie jakiego widoku uzyje i jakiego modelu uzyje.

Po drugie: nie kazda akcja potrzebuje modelu. Nawet polowa akcji nie wymaga modelu. Zobacz np. akcje DodajNowosc. Zadne dane nie pobierana sa z bazy (w naszym przykladzie). Akcja uzywa tylko widoku.

Bywa tak, ze akcja uzywa tylko modelu, widoku zas nie. Np: ZapiszUzytkownika.

Ko9lejna sprawa to uzywane kilku modeli w akcji. Zerknij:

  1. <?php
  2. // Akcja Pokaz zdjecia
  3.  
  4. $album = // pobierz id albumu do wyswietlenia z adresu url;
  5.  
  6. $oAlbym = new Model_Album($album);
  7. $id_autora = $oAlbum->getAuthor();
  8.  
  9. $oAutor = new Model_User($id_autora);
  10. echo 'Album nalezy do ' . $oAutor->getName();
  11. ?>


Nie mozesz wiec automatycznie ladowac widoku i modelu do akcji. Zrob klase bazowa dla akcji np. Action.
Kazda klasa akcji z niej dziedziczy.
Action posiada uzyteczne metody getModel($sModel), getView($sView). Kiedy potrzebujesz modelu/widoku po prostu piszesz w swojej akcji:

  1. <?php
  2. $oWidok = $this->getView('DodajUzytkownika');
  3. ?>


Co z walidacja?

Zajgorsza czesc aplikacji. Zawsze zajmuje najwiecej czasu i zawsze jest nudna winksmiley.jpg Nie zastanawialem sie jak zrobie to w nowymn frameworku, ale poprzednio mmialem cos w stylu:

  1. <?php
  2. // akcja DodajUzytkownia;
  3.  
  4. if(formularz nie przeslany) // czyli musimy go wyswietlin
  5. {
  6. $oView = $this->getView('DodajUzytkownika');
  7. $oView->display();
  8. return;
  9. }
  10.  
  11. // form przeslany, sprawdzamy dane:
  12.  
  13. $name = pobierz pole name z formularza;
  14.  
  15. $aErrors = array(); // tablica z komunikatami o bladach.
  16.  
  17. if(empty($name) || strlen($name) > 128)
  18. {
  19. $aErrors[] = 'Niepoprawna nazwa uzytkownika';
  20. }
  21.  
  22. // tu inne testy.
  23.  
  24. if(count($aErrors)) // czy wystapily jakies blady
  25. {
  26. $oView = $this->getView('DodajUzytkiownika');
  27. $oView->set('Errors', $aErrors);
  28. $oView->display();
  29. return;
  30. }
  31.  
  32. // tu odpalamy model i dodajemy uzytkiownika.
  33. // na koniec robimy:
  34.  
  35. $this->forward('PokazUzytkiownikow');
  36. ?>


Pozdrawiam, Adrian.
Go to the top of the page
+Quote Post
thornag
post
Post #18





Grupa: Zarejestrowani
Postów: 504
Pomógł: 2
Dołączył: 31.03.2006
Skąd: Londyn

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


Hmm, duzo dalo mi to do myslania, tymbardziej ze przed chwilka mialem rozmowe ze znajomym programujacym w Javie. Do tej pory myslalem ze model odpowiedzialny jest za cala logike i to on steruje wszystkim. Z tego co zrozumialem z Twojego postu, nie bede sie upieral ze dobrze, wychodzi na to ze tak naprawde akcja jest plikiem wykonywalnym, ktora steruje i dobiera sobie i widok i model, ktory jak sadze zajmuje sie tylko przechowywaniem danych (takie kontener na dane).


Mamy plik index.php i url index.php?akcja=viewUser&id=4

Plik index.php includuje plik akcje/viewUser.php a w tym pliku mamy to wszystko o czym wspomniales czyli
tak naprawde na sztywno wpiety kod.
1. Zainicjowanie modelu/klasy User (tutaj wszystko sie wczytuje do wlasniciowsci obiektu);
2. Dodanie wlasciwosci User(username etc) do szablonu np smarty.
3. Display widok taki czy taki.

Jesli user chce zmienic swoje dane to zmienia formularz klika submit ktory prowadzi do index.php?akcja=modifyUser&id=4 i tutaj

1. Akcja inicjalizuje model User.
2. Wrzuca do niego zmienne POST
3. Zapisuje wszystko z bazie danych
4. Robi forward(viewUser) ktory robi to co opisane wyzej.

Jesli dobrze zrozumialem to mam dwa kolejne pytania. Jaka role ma w tym wszystkim kontroler ? Co on kontroluje. I co z obiektem User ktory po przekierowaniu z formularza zostal utworzony ponowanie z wszystkimi wlasciwosciami i zapisany. Czy po akcji modifyUser gdy wywoluje akcje viewUser mam ladowac dane do obiektu/modelu jeszcze raz ? Jak to rozwiazac ?


EDIT

Przeczytalem caly temat jeszcze z dwa razy i wyciagnalem troche dodatkowych informacji smile.gif Moje pojmowanie wyglada teraz tak.

Mamy request http://www.domena.pl/action=viewUser&userid=1.

W pliki index.php mamy (pseudokod)

  1. <?php
  2.  
  3. $oCtrl = New Ctrl();
  4.  
  5. $sAction = $oCtrl->getParam('action');
  6. $oAction = New $sAction();
  7. $oView = $oAction->Execute(); // tutaj akcja prosi o dane i wstawia je do "zmiennych szablonowych" i ustawia widok
  8. $oView->Display();
  9. ?>


Kontroler narazie zostawie, moja akcja viewUser

  1. <?php
  2. class viewUserAction extends Action {
  3. public function Execute() {
  4.  $oCtrl = Ctrl::getInstance();
  5.  $intUserId = $oCtrl->getParam('userid');
  6.  $oUser = New UserModel($intUserId); //model sam sobie pobiera dane wedlug podanego ID
  7.  $oView = $oCtrl->getView('viewUsers');
  8.  $oView->setVar('username', $oUser->getUsername());
  9.  return $oView;
  10. }
  11. }
  12. ?>


Teraz widok

  1. <?php
  2. class viewUserViewextends View {
  3.  public funtion __construct() {
  4. $oSmart = New Smarty();
  5. $oSmart->setTemplate('usersList.tpl') //to taa pseudo metoda tongue.gif ogolnie zeby bylo wiadomo co sie dzieje.
  6. public function setVar($name, $value) {
  7.  $oSmart->Assign($name, $value);
  8.  }
  9.  public function Display() {
  10. $oSmart->Display() // to tez taka pseudometoda :)
  11. }
  12. }
  13. ?>


Czy to ogolnie ma jakis sens ?

Ten post edytował thornag 23.08.2006, 23:14:33


--------------------
"Wizja czasu jest szeroka, lecz kiedy sie przez nia przechodzi, czas staje sie waskimi drzwiami"

Go to the top of the page
+Quote Post
Ociu
post
Post #19





Grupa: Moderatorzy
Postów: 1 566
Pomógł: 37
Dołączył: 14.05.2003
Skąd: Kraków




Każdy sposób jest dobry, jeśli Ty uważasz, ze jest dobry. To jak ma działać Twój system to Twoja inicjatywa, a nie nasza. Jakby programiście mieli patrzyć, czy dobrze robią, nie powstały tak świetne frameworki jak mojavi, prado, symfony. Byłba by tylko jedna wytyczna: "Czy to wg. Was jest ok". Nie, to robimy tak, aby inni mieli dobrze. Tak to będzie istniał tylko jeden framework. Dlatego trzeba narzuć swój tok myślenia.

To było by tyle winksmiley.jpg
Saluto!, Wojtek
Go to the top of the page
+Quote Post
thornag
post
Post #20





Grupa: Zarejestrowani
Postów: 504
Pomógł: 2
Dołączył: 31.03.2006
Skąd: Londyn

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


@Ociu No tak. Ale inni programisci mogliby stwierdzic np "o mlody w dobrym kierunku to idzie,mozna by powiedziec ze widzi sie tu wzorzec MVC, tylko to jakies takie malo elastyczne, pomysl co by bylo gdyby..." biggrin.gif
Jak to sie mowi po co wywazac otwarte drzwi, jesli ktos z gory widzi ze ten tok rozumowania jest bledny, bo to to to (a tu w konstruktorze lepiej to przekazac, a tu lepiej dziedziczyc bo costam), lepiej zeby opieprzyl mnie teraz niz zebym za jakis miesiac dwa moze wiecej odkryl smutna prawde ze cala praca poszla na marne bo od poczatku wychodzilem ze zlych zalozen.

@Prph
Cytat
actions/ - kontrolery akcji
models/ - modele
views/ - widoki
configurations/ - konfiguracje wszystkiego co zbudujesz na owym frameworku (np. akcji lub bibliotek, ktore bys mogl pozniej dodac.)


Mozesz wyjasnic co to sa kontrollery akcji a co jest w folderze configurations. Dalej mi to troche miesza.
I kolejne pytanie do Ciebie. Jesli w modelu wystepuje blad (np bledne zapytanie SQL) co wtedy robisz ? Wyrzucasz wyjatek ? jesli tak to jak go obslugujesz. Ja myslalem zeby uzyc do tego metody forward tylko mam problem z wymysleniem jak przekazac wiadomosc. Myslalem tez zeby w bloku Catch zawrzec instrukcje ktora mi bedzie ten wyjatek razem z mesgiem obslugiwala (np poprzez forward smile.gif).

I jeszcze jedno teoretyczne. Przypuscmy ze akcja ma za zadanie skontaktowac sie z modelem i zazadac od niego listy uzytkownikow. Lista jest pusta. Czy w tym przypadku najlepiej jest korzystac z (znowu) forward ? Na zasadzie if(!count($arUsers)) oCtrl->forward(jakas tam akcja).

Ten post edytował thornag 24.08.2006, 16:20:55


--------------------
"Wizja czasu jest szeroka, lecz kiedy sie przez nia przechodzi, czas staje sie waskimi drzwiami"

Go to the top of the page
+Quote Post

2 Stron V   1 2 >
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 Aktualny czas: 19.08.2025 - 16:00