Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MVC] Pytań kilka...
Forum PHP.pl > Forum > PHP > Pro > Archiwum Pro
Stron: 1, 2, 3, 4
bim2
Po co rozdzielac. Pisali Ci juz poco? Dajesz w akacji metode np. add_item() i w add_item() dajesz if($admin==ok) ;P itp. Nie rozdzialaj a dodaj kolejne akcje smile.gif
br-design.pl
No przeciez pisze ze nie wszystko jest "add_item" chocby sprawdzenie zamowien w sklepie internetowym czy np. sprawdzenie platnosci itd. To rzeczy ktorych nie mozna zrobic sensownie ifem, musi byc jakis panel.
bim2
Nie o to mi chodzi :|
mam cos takiego:
  1. <?php
  2. class SklepAction {
  3. function defaults() {} //domyslna akcja
  4. function add_item()
  5. {
  6.  if($admin)
  7.  {
  8. formularz dodania pliku
  9.  }
  10. }
  11. function show_zamowienia()
  12. {
  13.  if($admin)
  14.  {
  15. spis zamówien
  16.  }
  17. }
  18. }
  19. }
  20. ?>
I ja wywołałbym to tak: action=sklep&view=show_zamownienia (zmienan view tlkyo tak, mozna zmienić) I w czym problem?

PS. Pisałem z głowy ale powinno działac jeśli masz podobnie zbudowany Kontroller tongue.gif
br-design.pl
A nie uwazasz ze zbytnio generalizujesz? Taka klasa jak sklepAction ktora oprocz obslugi sklepu bedzie miala jeszcze akcje do zarzadzania np. zamowieniami, uzytkownikami itd zrobi sie mocno przepasna.

Moim zdaniem zamowienia powinny byc osobnym kontrolerem gdzies wlasie w panelu, a jak nie w panelu to przynajmniej powinna byc jakos zabezpieczona przed dostepem.

i wtedy mozna zrobic osobne akcje dla pokzywania zamowien, zmiany statusu, edycji itd.

A dzieki osobnemu front controllerowi (dla panelu) ktory przyjmie obowiazek sprawdzania autoryzacji na siebie, nie musimy sie o to martwic w kontrolerach administracyjnych.
bim2
Nie wiem... może i tak. Tylko teraz jak to zrobić? Osobny kontroller? No nie wiem, ja by dał w starym kontrollerze nową metodę. Np executeAdmin() itp. i ona zajeła by się prawami i czytała akcję np, newsA.action a modele newsA.model.php itd. Może bardziej zaawansowani cos powiedzą tongue.gif No albo zrobić osobny kontroller smile.gif
altruista
tak mnie meczy, w koncu odwazylem sie zaptac...

1.

Jest obiekt "pracownik" - dziedziczy z klasy GenericObject (odwzorowujacej tabele w bazie na obiekt) dodakowo sklada sie z innych obiektow dziedziczacych z GenericObject (np "opinia" - pracownik ma swoje opinie).


Pytanie 1:
Tworzac widok oparty na szablonie smarty, wypada przekazywac mu obiekt np typu "pracownik" zeby szablon sam siegnal do jego metod i powyciagal potrzebne dane (imie, nazwisko, opinie) czy lepiej dla widoku przekazac juz tablice asocjacyjna z wczesniej przygotowanymi danymi (to co w pierwszej propozycji wyciaga smarty, wyciamy wczesniej)... questionmark.gif


2.

kontroler.
1. odwiedzam strone wpisujac http://strona.pl/?action=showPracownicy w celu wyswietlenia wszystkich pracownikow
2. glowny kontroler, analizujac parametr "action" includuje klase showPracownicy.class.php, (kazda klasa zaladowana przez kontroler, ma okreslony interfejs), tworzy obiekt tej klasy i wywoluje jego metode 'exec(HTTPReq $req)' (obiekt 'req' grupuje paramtery przeslane od uzytkownika, w tym wypadku nie jest konieczne przeslanie)
3. Funkcja 'exec(HTTPReq $req)' pobiera model (klasa ktora zawiera wszystkie operacje na pracownikach 'dodaj', 'usun', 'pobierz' 'wyszukaj' itp) i wywoluje jego funkcje 'pobierzWszystkichPracownikow()'; funcka zwaraca tablice/kolekcje obiektow typu 'pracownik'

Pytanie2:
Lepiej bedzie utworzyc widok w metodzie 'exec(HTTPReq $req)' obiektu klasy showPracownicy (jak tworzyc to poprzednie moje pytanie), przypisac wszystko do szablonu i go wyswietlic, czy tez zwrocic nazad do kontrolera nazwe widoku + w jakis sposob opakowane dane potrzebne do wyswietlenia, i niech glowny kontroler (ten z ktorym laczy sie uzytkownik i ten ktory stworzyl obiekt typu showPRacownicy) sobie podopisuje zmienne do szablonu i go wyswietli?



Nie wiem czy dobrze rozumuje cala koncepcje tworzenia oprogramowania, ale wole zapytac niz zaczynac pisac i uczyc sie zlych nawykow...

Watpliwosci:
3. czy rozwiazanie typu http://strona.pl/?action=nazwaAkcji jest prawidlowe? (powstanie pewnie bardzo duzo plikow a katalogu /actions/

Myslalem ze mozna np zrobic (pewnie tak sie robi) http://strona.pl/modul/funkcja/parametry i wtedy glowny kontroler bedzie ladowal klase 'modul' (zawiera wszystkie funkcje jakie sa dostepne dla modulu) i wywolywal jego metode 'funkcja' przekazujac jej 'paramtery' + tablice _REQUEST. Rozwiazanie daloby umieszczenie w jednym miejscu wszystkich funkcji zwiazanych z jednym modulem (kolejny problem to czy modulem moze byc "pracownicy" wraz z wszystkimi funkcjami czy to jest zla idea)


4. Czy mozna uzyc stwierdzenia 'model' w stusunku do klasy operujacych (zawiera wszystkie funckje jakie mozna wykonac z obiektem, np wyszukiwanie, itp) na obiektach 'pracownik'?
LBO
Cytat(bigZbig @ 27.07.2006, 14:34:12 ) *
Ja nie wydzielam czesci administracyjnej. U mnie administrator widzi ten sam widok co zwykly user...

Gdzie wpisujesz te if'y? W pliku widoku (template'cie)? Czy w akcji zmieniasz templaty? Jeżeli, w pliku widoku jak radzisz sobie ze złożonymi zależnosciami? Na przykład: zwykły user, może tylko oglądać. Moderator oglądać i edytować. Administrator oglądać, edytować i kasować. Jak?

Pytam się, bo mam z tym problem i jestem za robieniem osobnej aplikacji administracyjnej.
Apo
Cytat(LBO @ 15.09.2006, 19:15:42 ) *
Gdzie wpisujesz te if'y? W pliku widoku (template'cie)? Czy w akcji zmieniasz templaty? Jeżeli, w pliku widoku jak radzisz sobie ze złożonymi zależnosciami? Na przykład: zwykły user, może tylko oglądać. Moderator oglądać i edytować. Administrator oglądać, edytować i kasować. Jak?

Pytam się, bo mam z tym problem i jestem za robieniem osobnej aplikacji administracyjnej.


Ja to rozwiązałem tak że każda akcja ma swój konfig a w nim wymagane grupy, czy ma być publiczna, czy dostępna po zalogowaniu oraz akcje domyślne w razie braku uprawnien.
Mam główną klase Access która kożysta z klas pomocniczych:
Config - czyta ustawienia z tablicy i udostępnia Api do ich obsługi,
Groups - sprawdza czy dany użytkownik należy do jakiejś grupy lub czy jest zalogowany etc...

W przypadku braku uprawnien do wykanania akcji jest ona forwardowana na domyślną z configu smile.gif
A w samych akcjach mamy dostęp do klasy user która trzyma jego dane i łatwo możemy sprawdzać uprawnienia itp.
LBO
Ale jak to wygląda w praktyce? Masz różne widoki dla różnych grup? Czy w samym widoku ustawiasz co ma być widoczne dla poszczególnej grupy?

Wydaje mi się, że najbardziej zgodne z wzorcem MVC są osobne widoki.
Apo
Cytat(LBO @ 15.09.2006, 20:15:50 ) *
Ale jak to wygląda w praktyce? Masz różne widoki dla różnych grup? Czy w samym widoku ustawiasz co ma być widoczne dla poszczególnej grupy?


Powiedzmy że mam za zadanie wyświetlić dodatkowe dane dla moderatora forum (przycisk: usun, edytuj, przenies) czyli w pliku widoku robi za pomocą Apletu (który ma dostęp do HttpContext, klasy Usera, Modelu) warunek:

plik widoku post.php
Kod
<h1>{$title}</h1>
<?php
if($this->user->hasGroup('moderator'))
{
echo '<a>Edutuj, zmien, usun</a>';
}
?>

dalsza czesc szablonu ....


Aplet 'user' ma metoda hasGroup która sprawdza czy user ma daną grupe:

  1. <?php
  2.  
  3. Aplet user extends Apos_View_Aplet {
  4.  
  5. public function hasGroup($name)
  6. {
  7. return $this->user->hasGroup($name);
  8. }
  9. }?>
LBO
Eeesshh, w Zend Framework jeszcze apletów nie wprowadzili :/ Chociaż w SVN jest już Zend_Acl i zarządzanie uprawnieniami jest łatwiejsze. Będzie trzeba się posiłkować zmiennymi dopisanymi do szablonu.
Apo
W ZF są helpery, a u mnie dziala to na tej samej zasadzie tyle że jak już mówiłem Aplet ma dostęp do HttpContext, klasy Usera, Modelu itp, a zwykły helper takich żeczy nie ma smile.gif
LBO
No nie wiem, nie wydaje mi się, że helpery mogą służyć do tego. Aplet to aplet (czy komponent jak kto woli). Ale można się pokusić o napisanie czegoś podobnego.

Kontekst można uzyskać łatwo:
  1. <?php
  2. Zend_Controller_Front::getInstance(); // Na takiej zasadzie działa Zend_View_Helper_Url - jeszcze w inkubatorze.
  3. ?>

Dostęp do dodatkowych klas i modułów również:
  1. <?php
  2. Zend::register(); // zapisywanie OBIEKTU w rejestrze Frameworka
  3. Zend::registry(); // odczytywanie OBIEKTU z rejestru.
  4. ?>


Cytat
tyle że jak już mówiłem Aplet ma dostęp do HttpContext, klasy Usera, Modelu itp, a zwykły helper takich żeczy nie ma


Heeh, ale kontrolery też nie, przyzwyczaiłem się, że w tej fazie projektu, szkielet aplikacji trzeba stworzyć samemu.
Prph
Cytat(Apo @ 15.09.2006, 21:42:03 ) *
W ZF są helpery, a u mnie dziala to na tej samej zasadzie tyle że jak już mówiłem Aplet ma dostęp do HttpContext, klasy Usera, Modelu itp, a zwykły helper takich żeczy nie ma smile.gif


Podobnie u mnie, ale helpery maja dostep do aktualnego widoku (tj. do widoku, ktory je wywoluje). Dodalem taka funkcjonalnosc, poniewaz byla mi potrzebna. Mam dwa helpery - css oraz js - ktore pozwalaja zaladowac css i javascript do szablonu. Mowa tutaj o widoku dekorujacym, w ktorym mam szablon glowny (Main.php) zawierajacy np. naglowek, menu itp.

Zachecam do zapoznania sie z moim frameworkiem Rapide. Pisalem o nim na forum Temat: Framework Rapide Framework. W skrocie powiem, ze Rapide jest podobny do Zend Framework, poniewaz organizacja zostala oparta na tej spotykanej w ZF. Framework jest znacznie bogadszy od ZF i zawiera m.in. aplety, helpery, acl, user, language.

Pozdrawiam, Adrian.
Jarod
Cytat(rzseattle @ 28.01.2004, 16:03:04 ) *
(...)
1) Router "dekoduje" url i wysyla do kontrolera jak akcje ma uruchomic
2) Kontroler sprawdza czy akcja potrzebuje zalogowania , czy jest plik akcji itd...
3) Kontroler uruchamia akcje.
(...)

Kontroler to nic innego jak switch
  1. <?php
  2. switch(intval($_GET['wartosc_parametru']))
  3. {
  4. case 1:
  5. case 2:
  6. case 3:
  7.  etc..
  8. }
  9. ?>

czyli router i kontroler to jest to samo.. :/


Cytat(bumelang @ 4.02.2004, 15:30:08 ) *
(...)
Działa to tak: użytkownik wysyła żądanie w sensie HTTP, np. wypełnia jakiś formularz i klika "Submit", gdzie akcja formularza jest ustawiona na skrypt, w którym znajduje się kontroler. Ten łączy się z modelem, wywołuje tam jakieś metody biznesowe i gdy te zwrócą mu już efekty swojej pracy, to w zależności od tego, jakie one są, przekazuje to wywołanie do odpowiedniego widoku, czyli odpowiedniej strony php (która może być napisana w Smarty). W php w najprostszym wariancie może być to po prostu
  1. <?php
  2. /* Kontroler */
  3. if($model->zaloguj($login, $haslo) == SUCCESS) //wywołanie modelu
  4. include("strona_glowna.php"); // wywołanie widoku
  5. else
  6. include("blad.php"); // wywołanie innego widoku
  7. ?>

(...)

Z całym szacunkiem ale ja dopiero zagłębiam się w MVC. Rozważmy inny przykład:
Na stronie index.php pojawia się tylko okienko logowania. Jeśli login i hasło są prawidłowe to użytkownik sotaje przenoszony do system.php, gdzie ma dostęp do modułów (tylko do tych na które pozwalają uprawnienia przypisane danemu użytkownikowi w bazie danych).

Jakby to wyglądało?
1. Uruchamiany jest widokLogowanie
-użytkownik wpisuje login i hasło po czym naciska submit
2. Kontroler pobiera login i hasło i przekazuje do modelu w formie zalogujUser($login, $haslo);
3. Jeśli dane są poprawne to pobierz uprawniena danego usera i załaduj widokSystem
- w przeciwnym wypadku wyświetl WidokBłąd

Dobrze myślę? Czyli widok jest wywoływany jeszcze zanim kontroler sprawdzi podejmie decyzje o logowaniu..
mariuszn3
Router jest częścią kontrolera, która tłumaczy url na zmienne na podstawie których dalszy algorytm kontrollera wywołuje akcję.
NuLL
Cytat(mariuszn3 @ 24.11.2006, 18:41:53 ) *
Router jest częścią kontrolera, która tłumaczy url na zmienne na podstawie których dalszy algorytm kontrollera wywołuje akcję.

Router nie powinien byc czecia kontrolera gdyz z adresu mozna wyciagnac troche wiecej niz tylko akcje do wykonania. Router powinien nalezyc do requestu i z adresu wyciagac zmienne getowe.

EDIT - teraz zalapalem tongue.gif
mariuszn3
NULL myślę, że za bardzo rozwarstwiasz pewne rzeczy.. jeśli nie częścią kontrolera to częścią czego? Widoku czy Modelu?
Kiedy piszę o kontrolerze piszę o jednej z trzech warstw abstrakcji, która odczytuje żądanie (którego nośnikiem jest między innymi adres url) a nie o konkretnej jednej klasie.
Jarod
Cytat(Seth @ 17.12.2004, 13:12:42 ) *
@hamlecik:
Ja to robie w ten sposob:
Mam jeden glowny kontroler, ktory pobiera dane od usera i na ich podstawie odpala odpowiednia akcje, ktora jest w konfigu.

I za każdym razem, kiedy wywoływana jest akcja odczytujesz konfiga? Czy to nie zwalnia aplikacji?
Czy może gdzieś na samym początku (ale gdzie?) parsujesz konfiga i każdy parametr ustawiasz jako zmienną sesyjną, żeby nie gubic przy przeładowaniach strony?
UDAT
Cytat(J4r0d @ 24.11.2006, 20:02:23 ) *
I za każdym razem, kiedy wywoływana jest akcja odczytujesz konfiga? Czy to nie zwalnia aplikacji?
Czy może gdzieś na samym początku (ale gdzie?) parsujesz konfiga i każdy parametr ustawiasz jako zmienną sesyjną, żeby nie gubic przy przeładowaniach strony?

Raz. Wystarczy cache'owanie konfiga.
Ustawianie jako zmiennej sesyjnej mija się z celem, zmiana conifg'u może nastąpić teraz jednak dopiero za np. 12h zmienii się to dla user'a który będzie mocno używał twoją aplikację.

Dwa. Jak trzymasz konfiga w bazie to zapis do zmiennych sesyjnych jest nieopłacalny wydajnościowo, możesz mieć ogromnego config'a ale potrzebować 1% danych z niego.
Jarod
Cytat(UDAT @ 26.11.2006, 13:12:37 ) *
Raz. Wystarczy cache'owanie konfiga.

Ale odczyt z pliku co jakąś akcje też obciąża.

Cytat(UDAT @ 26.11.2006, 13:12:37 ) *
Ustawianie jako zmiennej sesyjnej mija się z celem, zmiana conifg'u może nastąpić teraz jednak dopiero za np. 12h zmienii się to dla user'a który będzie mocno używał twoją aplikację.

Wyjaśnij to bo zamotałeś i nie wiem o co Ci chodzi..

Cytat(UDAT @ 26.11.2006, 13:12:37 ) *
Dwa. Jak trzymasz konfiga w bazie to zapis do zmiennych sesyjnych jest nieopłacalny wydajnościowo, możesz mieć ogromnego config'a ale potrzebować 1% danych z niego.

Tu się zgodze..
NuLL
Cytat
Ale odczyt z pliku co jakąś akcje też obciąża.

Tysieczne czesci sekundy winksmiley.jpg
Jarod
Zauważyłem w swoich projektach, że duża część kodu powtarza się. Przyglądałem się frameworkom, które były prezentowane przez użytkowników tego forum jak i innym. Podoba mi się np, Rapide ale jak na razie jest za duży dla moich potrzeb. Chcę spróbować napisać sobie zestaw kilku prostych klas i zaimplementować MVC. Czytałem ten temat mnóstwo artykułów i każdy inaczej rozumie ten wzorzec. Spróbuje zebrać to co zrozumiałem - jeśli się mylę to mnie poprawcie:

1. Model - odpowiedzialny za logikę biznesową, jest jedyną częścią aplikacji, która przechowuje dane. Sposób przechowywania jest obojętny (baza, plik, itp.) Dobrym sposobem implementacji modelu jest utworzenie odzielnej klasy dla każdego logicznego obiektu, np. klasa Produkty, która będzie pobierać dane o produktach lub klasa Uzytkownicy, która będzie pobierać listę zarejestrowaych użytkowników... Jeśli dane są przechowywane w bazie danych, zazwyczaj jedna klasa odpowiada jednej tabeli lub kilku tabelom ściśle powiązanych ze sobą.

Spotkałem się też z twierdzeniem, że dobrze zaprojektowany model powinien być odporny na wewnętrzne zmiany w strukturze tabel bazy. I tu uważam, że jest to ciężkie do zrealizowania. Bo jeśli klasa Użytownicy pobiera dane wskazanego użytkownika (np. imie, nazwisko, pesel, data zarejestrowania itp, to po zmianie struktury trzeba zmieniać zapytanie..)


Widok - odpowiada za prezentacje danych. Wykorzystuje model do pobrania danych. Widok powinien utworzyć instacje klas modelu i wywołać metody odpowiedzialne za pobranie danych. Widok nie może modyfikować danych. Widok nie jest szablonem, pobiera dane i includuje odpowiedni szablon.

Kontroler - na podstawie analizy żądania http powinien zdecydować jakie akcje wykonać i jaki widok wyświetlić. Kontroler to jeden główny plik zbudowany na switchu..


PYTANIA:
1. Jeśli widok nie może zmieniać danych, to jak odbywa się aktualizacja (np. zmień hasło użytkownikowi) ?

Kontroler odbiera żądanie zmień hasło i wywołuje odpowiednią akcje, która uruchamia widok z formularzem zmiany hasła. Ten formularz wywołuje.. co? Znowu kontroler czy inną akcje, która zmienia hasło i odpala widok z komunikatem udanej zmiany/nieudanej zmiany ?

2. Wiele z osób torzy jeszcze klasy Request i Response. Po co?
NuLL
Cytat
Kontroler to jeden główny plik zbudowany na switchu..

laugh.gif U mnie projekcie wartwa kontrolera to 8-10 klas - zalezy od jego konfiguracji

Ja warstwy modelowej nie stosuje wiec sie nie znam winksmiley.jpg

Cytat
2. Wiele z osób torzy jeszcze klasy Request i Response. Po co?
Nikt ich nie wymaga. A po co je sie robi questionmark.gif Aby zadanie HTTP mialo ladna otoczke.
Sh4dow
Cytat(J4r0d @ 2.12.2006, 11:16:30 ) *
...
1. Jeśli widok nie może zmieniać danych, to jak odbywa się aktualizacja (np. zmień hasło użytkownikowi) ?

Kontroler odbiera żądanie zmień hasło i wywołuje odpowiednią akcje, która uruchamia widok z formularzem zmiany hasła. Ten formularz wywołuje.. co? Znowu kontroler czy inną akcje, która zmienia hasło i odpala widok z komunikatem udanej zmiany/nieudanej zmiany ?

2. Wiele z osób torzy jeszcze klasy Request i Response. Po co?

ad. 1 Sam napisałeś Model zajmuje sie całą logiką, On otrzymuje polecenie wykonania zmiany hasła, zwraca powiedzmy wartosc bool ktora okresla czy sie to udalo czy nie a widok na tej podstawie podaje wiadomosc z potwierdzeniem lub błędem.

ad. 2 Jesli chodzi klasy Request/Response to czesto jest to połączone z jakimiś filtrami, validatorami. Pobierajac jakas dane powiedzmy POST mozesz rzadac ze to ma byc liczba i jesli sie nie zgadza zwracasz false/null/error (dowolnie, w zaleznosci od uznania) lub tez mozesz przefiltrować zmienna i wszystkie nie cyfry wywalici znowu cos tam zwrocic.
Jarod
Początkowo kontroler wydawał mi się najłatwiejszy (myliłem się). Dorwałem frameworka i załapałem widok, model i jak to działa. Wiem jak ogólnie działa kontroler ale nie mogę załapać jak napisać i połączyć w wspólne działanie Request/Response.. :/

Mógłby mi to ktoś wyłumaczyć prostym przykłądem (dwie przykładowe klasy i jak to połączyć)?
jastu
Przyłącze się do prośby ... ja jestem juz po wybieraniu z urla potrzebnych informacji,operowania na nich , problem mam natomiast z generowaniem wyniku operacji .


//edit
Jak klasa specjalizująca może dodawać funkcjonalności nadklasie ? (jeśli dobrze rozumiem o co chcę zapytać )

Czy mógłby ktoś naszkicować diagram (uml) do elementu głównego dla wzorca MVC ( np obiekt page jako obiekt który powstaje z innych klas dzięki dziedziczeniu,kompozycji bądź innch) , poglądowy - jak połączyć klasy ? . Rozumiem częściowo jak klasy mogą przekazywać sobie wyniki operacji na obiektach , ale jeszcze mi czegoś brakuje
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.