Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MVC] Podział aplikacji?
Forum PHP.pl > Forum > PHP > Pro > Archiwum Pro
raikou
Witam

Mam trzy pytania odnośnie wzorca MVC, byłbym wdzięczny za wszelkie wskazówki.

1) Co powinno znaleźć się w modelu? Rozumiem że np. wszelkie funkcje dotyczące konretnych zadań nie związanych z wyświetlaniem danych. Czyli w takim razie klasa do zarządzania użytkownikami będzie modelem?

2) Filtracja i walidacja danych wejściowych, które mają mieć jakiś określony typ, powinna się odbywać w kontrolerze czy modelu? Nie mówię tutaj o zapisie do bazy/pliku, ta filtracja jest w osobnym DAO.

3) Wielojęzyczność strony mam rozumieć powinna być w zaimplementowana gdzieś w elemencie widoku?
Ludvik
1. Model to dane oraz czynności wykonywane na nich, czyli po ludzku - symulacja przedstawianego środowiska. Nigdy nie starałem się odwzorować modelu na klasy, bo jest to dla mnie pojęcie abstrakcyjne...

2. Najczęściej dane zostają filtrowane w filtrach przed łańcuchem akcji. Poszukaj czegoś o wzorcu Intercepting Filter, to wyjaśni Ci się sprawa smile.gif

3. Tak powinno być, lecz niektóre elementy takie jak wersje językowe artykułów są pobierane przed wywołaniem widoku, więc pobranie odpowiedniej wersji artykułu, newsa czy czegokolwiek innego, nie przeszkadza w realizowaniu założeń wzorca. Aczkolwiek elementy interfejsu powinny być tłumaczone w widoku...
raikou
Cytat(Ludvik)
2. Najczęściej dane zostają filtrowane w filtrach przed łańcuchem akcji. Poszukaj czegoś o wzorcu Intercepting Filter, to wyjaśni Ci się sprawa

No tak. Takie filtrowanie sprawdzi się przy autoryzacji, wybieraniu lokalizaji użytkownika etc. Ale czy to odpowiednie miejsce żeby sprawdzać czy w polu formularza został wpisany poprawny adres email bądź pole nie zawiera tagów html?
sf
Ja mam w akcji metodę validation(), która właśnie jest odpowiedzalna za walidację.

  1. <?php
  2. // ...
  3.  /**
  4.  * Walidacja danych.
  5.  * 
  6.  * @param iRequest $oRequest
  7.  * @return array
  8.  */
  9. public function validate(iRequest $oRequest)
  10. {
  11. $aErrors = array();
  12.  
  13. $oV = new HValidation();
  14. if($oV->isEmpty($oRequest->name)) {
  15. $aErrors['name'] = 'emptyName';
  16. }
  17.  
  18. return $aErrors;
  19. }
  20.  
  21.  
  22. /**
  23.  * Uruchomienie akcji.
  24.  * 
  25.  * @param iRequest $oRequest  Przychodzące żądanie.
  26.  * @param iResponse $oResponse Przygotowywana odpowiedź.
  27.  */
  28. public function run(iRequest $oRequest, iResponse $oResponse)
  29. {
  30. // walidacja
  31. if($aErrors = $this->validate($oRequest)) {
  32. $oResponse->failed = $aErrors;
  33. return -1;
  34. }
  35. // ...
  36. ?>
marast78
Cytat(raikou @ 25.09.2006, 15:57:37 ) *
No tak. Takie filtrowanie sprawdzi się przy autoryzacji, wybieraniu lokalizaji użytkownika etc. Ale czy to odpowiednie miejsce żeby sprawdzać czy w polu formularza został wpisany poprawny adres email bądź pole nie zawiera tagów html?



tutaj najlepiej sprawdza się AJAX...lub poprostu DHTML i JS
Apo
Cytat(marast78 @ 30.09.2006, 18:10:26 ) *
tutaj najlepiej sprawdza się AJAX...lub poprostu DHTML i JS


A co jeśli user ma wyłączone js ;]

Nie wiem za badzo jak filtrować lub validować dane z formularzy za pomocą interceptiong filter, nigdy nie spotkałem sie z takim czyms ;/
Ludvik
Można dodać filtry wywoływane tylko przed konkretną akcją czy też łańcuchem akcji. Najprościej jednak dodać akcję sprawdzającą te dane przed wywołaniem akcji dodającej je do bazy. W przypadku niepowodzenia zawsze można przekierować kontroler do innej akcji, która wyświetli formularz z zaznaczonymi błędami.
raikou
Mimo wszystko raczej zdecyduję się na utoworzenie konretnych obiektów formularzy oraz zawarcie w nich metod sprawdzających poprawność danych. Jeden formularz dla dodawania i edycji newsa, posta etc.

Tworzenie kolejnych akcji w kontrolerze wydaje mi się problematyczne w momencie gdy jest sporo formularzy i każda zmiana w obiekcie widoku (formularz) pociąga za sobą zmiany w kontrolerze (walidacja).

Sprawdzanie samym JSem jest może fajne i wygodne ale co jeżeli ktoś prześle dane $_POST używając swojego formularza a nie mojego? Pomijając fakt że PDO wyeliminuje SQL Injection, będę miał bałagan w danych tongue.gif
Apo
Niewiem czy opłaca sie tworzyć jeszcze osobne klasy do każdego formularza aby je sparadzić, bo i tak trzeba robić klase widoku, model, kontroler no i by jeszcze klasa form doszła.

Narazie robie wielkie uproszczenie z walidacją:

  1. <?php
  2.  
  3. // jakis tam kontroler
  4.  
  5. public function addAction()
  6. {
  7. $view = $this->getView('ogloszenie');
  8. $view->add();
  9.  
  10. if($this->request->requestMethod() == 'POST')
  11. {
  12. $t['title'] = $this->request->post('s_title', 1);
  13. $t['price'] = $this->request->post('s_price', 1);
  14. $t['time_to'] = $this->request->post('s_timeto', 1);
  15. $t['category'] = $this->request->post('s_category', 1);
  16. $t['content'] = $this->request->post('s_content', 1);
  17. $t['autor'] = $this->getUser()->id;
  18. $t['time_from'] = time();
  19. $error = false;
  20.  
  21. foreach($t as $key => $value)
  22. {
  23. if(empty($value) || !isset($value))
  24. $error = true;
  25. }
  26.  
  27. if($error === true)
  28. {
  29. $view->errors = 'Prosze wypelnic wszystkie pola';
  30. $view->t = $t;
  31. }
  32. else
  33. {
  34. $model = $this->getModel('ogloszenie');
  35.  
  36. if($model->dodajOgloszenie($t))
  37. $view->errors = 'Ogloszenie zostalo dodane';
  38. }
  39. }
  40.  
  41. $view->fetch();
  42. }
  43.  
  44. ?>


Jak widać jest to nie estetyczne rozwiązanie. Lepiej stworzyć formularz dzięki xml i napisać jakąś 1 klase sprawdzającą i walidującą pola a na koncu wyświetlenie błędów.
Ludvik
Cytat(raikou @ 1.10.2006, 09:49:41 ) *
Mimo wszystko raczej zdecyduję się na utoworzenie konretnych obiektów formularzy oraz zawarcie w nich metod sprawdzających poprawność danych. Jeden formularz dla dodawania i edycji newsa, posta etc.

Tworzenie kolejnych akcji w kontrolerze wydaje mi się problematyczne w momencie gdy jest sporo formularzy i każda zmiana w obiekcie widoku (formularz) pociąga za sobą zmiany w kontrolerze (walidacja).

Sprawdzanie samym JSem jest może fajne i wygodne ale co jeżeli ktoś prześle dane $_POST używając swojego formularza a nie mojego? Pomijając fakt że PDO wyeliminuje SQL Injection, będę miał bałagan w danych tongue.gif

Tak, stworzenie systemu obsługi formularzy z walidacją jest najlepszym pomysłem, ale gdzieś trzeba utworzyc instancje tych klas. Najwygodniejszym momentem jak dla mnie jest odpowiednia akcja. Tak czy inaczej trzeba gdzieś potworzyć te obiekty, a akcja będzie jedynym miejscem, w którym to nastąpi, a co za tym idzie, jedynym kawałkiem kodu, który trzeba będzie poprawić przy zmianie widoku. To nie są chyba duże zależności smile.gif

Jeżeli masz jakieś schematy tworzenia formularzy (xml czy coś w tym stylu), to obiekty pewnie stworzysz dynamicznie w filtrach.
MMP
To ja zaprezentuje jak obsługa formularzy wygląda u mnie, na przykładzie dodawania nowego użytkownika
  1. <?php
  2. class fAddUser extends Forms {
  3. // Jeżeli pole nie jest type="input"
  4. protected $aFieldSubmit = array (
  5. 'AddUser'
  6. );
  7. protected $aFieldPass = array (
  8. 'UserPass'
  9. );
  10. // Definuje jakie warunki muszą byc spełnione by przepuscić formularz
  11. public function validate()
  12. {
  13. $this -> UserName() -> must();
  14. $this -> UserMail() -> mail();
  15. }
  16. // A tutaj sprawdzam i wysyłam błędy
  17. public function check()
  18. {
  19. if( $this -> UserName() -> errorMust() )
  20. {
  21. $this -> UserName() -> error( 'Musisz podać nazwe użytkownika' );
  22. }
  23. if( $this -> UserMail() -> errorMail() )
  24. {
  25. $this -> UserMail() -> error( 'Musisz podać prawidłowy mail' );
  26. }
  27. }
  28. }
  29. // Klasa akcji
  30. class aAddUser extends Actions implements iViews, iAppends, iModel, iInput, iForms
  31. {
  32. public function start()
  33. {
  34. // Tworze instancje
  35. new fAddUser;
  36. // Rozpoczyna inicjowanie fomularza
  37. $this -> to();
  38. }
  39.  
  40. // Wywoływanie gdy nie stwierdzi błędu
  41. public function resultAddUser( Forms $oForm )
  42. {
  43. // Sprawdzenie czy użytkowników lub mail istnieje
  44. $oUsers = $this -> append( 'UsersAndGroups' );
  45. if( $oUsers -> userExists( $oForm -> post( 'UserName' ) ) )
  46. {
  47. $oForm -> UserName() -> error( 'Taki użytkownik już istnieje' );
  48. $bError = 1;
  49. }
  50. if( $oUsers -> mailExists( $oForm -> post( 'UserMail' ) ) )
  51. {
  52. $oForm -> UserName() -> error( 'Taki mail już istnieje w bazie' );
  53. $bError = 1;
  54. }
  55. if( $bError )
  56. {
  57. return;
  58. }
  59. // Wykonanie dodania użytkownika
  60. $oUsers -> addUser( $oForm -> post() );
  61. $oModules = $this -> append( 'Modules' );
  62. $iUser = Db::getInstance() -> lastInsertId();
  63. $oUsers -> addToGroupRegister( $iUser );
  64. if( $oModules -> isOn( 'Auth' ) )
  65. {
  66. $this -> assign( 'iUserAuth', $iUser );
  67. }
  68. $this -> assign( 'iUser', $iUser );
  69. Output::getInstance() -> redirectAfterForm();
  70. }
  71. }
  72. ?>

A w widoku opieram się na funkcjach formularza: form, error, isError, field.
Turgon
Ja tutaj wcisnę swoje pytanie z zupełnie innej beczki. Gdzie i kiedy najlepiej tworzy egzemplarz klasy request ? Czy do niej wsadzać parameters z path_info ?
Ociu
Instancja requesta tworzona jest w kontrollerze. To ona odpowiada za dane wejściowe do systemu. Ona sprawdza dane czy są poprawne ($_GET). To poprzez nią pobierasz dane z tablicy POST.

Także nie ma co zapychać go parametrami z path_info, stwórz sobie do tego ParameterHolder. smile.gif
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.