Vengeance
1.01.2005, 15:35:12
ee ale to w sumie jest dowolne! nie przesadzajmy ze jesli hawk powie to i to to jest to wlasnie MVC a cala reszta nie.
MVC takze nic nie mowi o akcjach przeciez! ich nawet nie musi byc.
Pozatym wzroce sa po to takze aby je naginac

(czesto tak powstaja nowe wzroce) hehe ;]
Żeby wyjaśnić rozbieżności:
Diagram to nie implementacja. Jeżeli kontroler ma uruchomić po prostu widok, i nie ma żadnej modyfikacji (czyli nie potrzeba do tego specjalnej akcji), to jak to zrobić? Można sobie wyobrazić taką implementację, gdzie bezpośrednio wykonywany jest widok (np. phiend), lub taką, gdzie potrzebna jest jakaś minimalna akcja, która odpali ten widok (tak ma większość). To kwestia tego, jak sie napisze framework. Ale idea jest ta sama - nie ma żadnej modyfikacji, chcemy wyświetlić widok jak najmniejszym kosztem.
bregovic
1.01.2005, 17:42:32
Hmm... Hawk, podsumowywując - nie ma znaczenia czy nazwiemy to akcją, czy widokiem, czy czymkolwiek - to musi być jakaś klasa, która coś wyświetli. W przypadku phienda, są to klasy z funkcją display - które ewentualnie łączą się z modelem i wyświetlają output (np. przy pomocy smarty).
Innym rozwiązaniem (które tak na prawdę jest dokładnie tym samym - z tymże z innymi nazwami) jest stworzenie akcji - które nie robią nic innego jak wyciągnięcie danych z bazy i wyświetlenie ich.
Różnica, z tego co widzę polega na ilości kontroli jaką przekażemy widokowi. Mnie, wydaje się że widok jako taki nie powinien mieć dostępu do modelu - bo zbyt komplikuje to implementację. Wydaje mi się że to kontroler (więc i akcje) powinien pracować na api modelu - a widok powinien zająć się wcale niełatwą sprawą wyświetlania danych...
Czy się mylę?
Vengeance
1.01.2005, 17:59:09
@bregovic: krotka mowiac myslisz o tworzeniu widoku przez akcje
i przekazywaniu mu jakos (glownie przez parametry w konstruktorze)
jedynie wyniku jakis tam operacji na modelu (pobierania danych).
Z tego co widze bo roznych przygladach wiele skryptow przekazuje do
widoku instancje modelu aby ten zrobil sobie "co potrzebuje". Jednak moze zrobic takze cos wiecej. A w przypadku rozwiazania podanego powyzej mialby dostepdo tego co naprawde jest mu koniecznie.
Czy tak?
DaNTe
24.01.2005, 12:47:08
Podłącze się pod temat, żeby nie zakładać nowego

Jestem na etapie budowania aplikacji w oparciu o phiend (co prawda to tylko podstawa, którą trzeba dosć mocno rozbudować, ale zawsze).
Z tego co zdążyłem się zorientować, nie ma tutaj matod dających dostęp to parametrów POST, GET itp, a jako, że nie bardzo chcę operować na nich bezpośrednio - muszę sobie taki kawałek kodu dopisać.
Problem jest właśnie z parametrami GET

bo prawdopodobnie czasami na wywołania nałożony będzie mod_rewrite, zresztą ze standardową postacia index.php/moja/akcja/ też nie ładnie wyglądały parametry get przekazane po znaku zapytania.
I tu właściwe pytanie - jak radzicie sobie z wywolaniami w stylu /artykul/15/strona/6 ?
Jakieś idee poza ręczną analizą REQUESTED_URI - którą defacto powinien odwalić rontroler ?
hawk
24.01.2005, 13:11:39
Jeżeli chodzi o index/nazwa/akcji, to na pewno możesz to zrobić za pomocą standardowego phienda. Tak działa np. strona projektu.
Jeżeli chodzi o artykuł/16/strona/5, to istotnie kontroler powinien takie coś odwalić. Ale sam framework nie, bo nie wie nic o artykułach. W zależności od tego, ile akcji potrzebuje takich danych, można wydziedziczyć wszystkie/niektóre akcje z abstrakcyjnej klasy, która parsuje takie coś i wyciąga to co potrzeba.
Można też przyjąć, że url zawsze ma postać cośtam/nazwa/wartość/nazwa2/wartość2 itd. Tego phiend automatycznie nie parsuje, i wtedy najlepiej chyba byłoby zrobić klasę bazową dla wszystkich akcji.
aleksander
9.02.2005, 18:22:42
ok no więc ja poruszę troche inny temat MVC. Jest to własciwie tylko małe uniedogodnienie, ale czasem może wkurzyć. Być może ja coś źle robię.
mam akcję showcomments. W tej akcji są wyświetlane komentarze i formularz do wstawienia nowego komentarza. Gdy kliknę na przycisk dodaj komentarz, przejdę do akcji addcomment. Ta akcja zwróci nazwę widoku showcomments, wieć znowu zobaczę komentarze, ale w pasku adresu będzie nadal addcomments i gdy użytkownik niechący lub chcący kliknie F5 to do bazy znowu doda się identyczny komentarz (pomijam, że przeglądarka ostrzega przed tym).
Można by w akcji addcomment zrobic header( 'Location'); do akcji showcomments i po problemie, ale to z kolei odbiera od zasady MVC. Co Państwo o tym myślą?
pozdrawiam
Można zwrócić widok z tekstem "komentarz został dodany..<a>zobacz komentarze</a>"
sobstel
9.02.2005, 19:55:19
albo po prostu uneimożliwić dodanie takiego samego komentarza, poprzez sprawdzeni przy dodawaniu do bazy czy nie istnieje juz dokladnie taki sam rekord (pomijając czas oczywiście, no i trzeba uważać żeby przy okazji nie zablokować użytkownikowi możliwości wielokrotnego postowania popoularnych fraz np. "ok")
nawiasem mówiąc, przy okazji implementujemy mały mechanizm anty-floodowy.
marcin96
10.02.2005, 15:04:30
Cytat
Można by w akcji addcomment zrobic header( 'Location'); do akcji showcomments i po problemie, ale to z kolei odbiera od zasady MVC. Co Państwo o tym myślą?
Czemu odbiega? Zrobić widok wykonywany po wykonaniu akcji dodania komentarza do bazy. Widok ten wysyła do użytkownika właśnie header("Location: ..."); i tyle...
hawk
10.02.2005, 16:50:22
Fakt, nie odbiega. Patrz np. phrame.
A generalnie to po prostu potrzebna jest kontrola postback. A przekierowanie jest właśnie jedną z takich metod.
Zresztą można nawet puścić header już w początkowej akcji. Redirect i tak jest tylko wewnętrznym trikiem, a nie widokiem.
squid
9.03.2005, 13:57:27
czy mozna laczyc MVC z innymi wzorcami, ktos juz tak probowal?
M4chu
9.03.2005, 15:51:00
Mozna? Nawet trzeba! Np Dao, Intercepting Filter, Decorator (do widoku).
Btw sam MVC jest zbudowany na Composite, Observer, Strategy i pewnie jeszcze kilku
Witam!
I ja pozwolę sobie dołączyć się do dyskusji

Zacząłem właśnie pisać własny framework. Początkowo miał to być CMS, ale stopniowo ewoluowało do frameworka. Planuję wykorzystać model MVC, jednak męczy mnie parę kwestii...
Po pierwsze:
We wprowadzeniu do MVC wyczytałem że powinien być tylko jeden kontroler. Co w sumie logiczne jest jeśli system ma być elastyczny i łatwo się dopasowywać poprzez wyedytowanie configa. Jednak problem pojawia się jeśli chcemy zastosować do tego czegoś subdomeny. Mamy dany kontroler kontroler.php. I teraz w zależności od parametrów przekazanych do niego chcemy wyświetlić dział newsy albo czat. Czyli kontroler.php?dzial=newsy kontroler.php?dzial=czat I wszystko ładnie i pięknie do czasu aż wprowadzimy subdomeny. newsy.domena.pl czat.domena.pl I co się wtedy dzieje? Wychodzi na to że trzeba zastosować kilka kontrolerów. Chyba że... wykorzystać mod_rewrite, ale ten nie zawsze jest dostępny. Można też teoretycznie wykorzystać stronę błędu 404 do "emulacji" mod_rewrite ale to rozwiązanie mało eleganckie. A jeśli podzielimy kontroler to znowu stracimy możliwość łatwej konfiguracji i system w ten sposób będzie mało elastyczny (właściwie przypisany do jednego konkretnetego rozwiązania - czyli przestanie być frameworkiem). Może więc w każdej subdomenie dać plik index.php, w którym wysyłać header Location, przekierowujący do kontrolera i przekazujący mu wszystkie parametry? To też rozwiązanie mało eleganckie i rozwiązujące problem tylko częściowo. A może są jeszcze jakieś ciekawe rozwiązania tego problemu?
Druga sprawa:
Druga? W trakcie pisania tego postu przyszło mi do głowy kilka pomysłów na rozwiązanie pozostałych problemów

Pozdrawiam
Ociu
11.08.2005, 09:50:50
Ja mam coś takiego: localhost/język/content(lub forum, chat)/moduł/opcja/id/
przykładowo: localhost/pl/content/articles/show/1/
Do subdomen, można by rzeczywiście użyć mod_rewrite... jaki w tym problem ?
Vengeance
11.08.2005, 10:49:32
przecież każda subdomena może wskazywać na ten sam katalog, z tym samym index.php i kontrolerem, a kontroler sprawdzi poprawność $_SERVER[HOST].
Jeżeli stwierdzi, że ma doczynienia z odwołaniem z subdomeny, ustala np. katalog z którego ma brać akcje np. /actions/chat/*
Pozatym do tego służy także wzorzec FrontControllera pozwalający utworzyć "jeden spójny punkt wejścia" do aplikacji.
max_catch
27.08.2005, 18:22:48
Mam pytanie z nieco innego obszaru. Nie dysponuję gotowym kodem, rozważam jedynie teoretycznie, ale postaram się przedstawić moje wątpliwości w miarę zrozumiale.
Rozpatrując modularyzację aplikacji wygodna jest możłiwość wykonywania sekwencji akcji (czy też łańcuchów akcji; być może mylę pojęcia) przy czym akcje te mogą być dynamicznie kolejkowane w trakcie wykonywania dowolnej akcji.
Przykład: stronę tworzą takie komponenty: drzewiaste menu (np: katalog produktów w e-sklepie - kategorie), lista produktów (główna treść), pole wskazujące w jakim miejscu strony jest użytkownik. Aby wygodnie rozdzielić zadania i ułatwić edycję, każdy z wymienionych komponentów strony może być realizowany oddzielną akcją i wywoływany w zbiorczej akcji, choćby tak:
<?php
class Store extends Action {
public function perform(httpRequest $request, httpResponse $response) {
// kolejkowanie potrzebnych elementów, czyli tworzenie omawianej sekwencji akcji
Controller::getInstance()->enqueue('displayCatalog');
Controller::getInstance()->enqueue('displayLocation');
Controller::getInstance()->enqueue('displayProducts');
}
}
?>
w takiej sytuacji kontroller otrzymawszy żądanie 'www.test.com/go/Store' podczas inicjalizacji wprowadza do swojej wewnętrznej listy akcji nazwę akcji do wykonania (tutaj 'Store', nie jest uzasadnione wprowadzanie na listę gotowego obiektu). Kontroler startuje; podczas wykonania Store zakolejkowane zostają 3 kolejne akcje i pętla wykonawcza sunie dalej.
A teraz sedno sprawy.
Na platformie MVC potrzebujemy także filtrów. Moje pytania dotyczą wzajemnych relacji między akcjami a filtrami.
1. Czy wykonanie łańcucha akcji powierzać samemu kontrolerowi, czy może kontroler powinien wykonywać jedynie szereg filtrów, z których ostatni będzie filtrem ExecutionFilter i jemu przekazywać kontrolę nad sekwencją akcji? Jakie są korzyści zastosowania każdego z rozwiązań?
2. Czy wykonanie akcji w sekwencji wiązałoby się z wykonaniem osobnego szeregu filtrów dla każdej akcji? Czyli czy łańcuch filtrów to pomysł, który powinno się stosować przed wykonaniem łańcucha akcji, czy też dla każdej akcji w łańcuchu indywidualnie?
Podsumowując, chciałbym abyście podzielili się swoimi pomysłami na rozwiązanie problemu "interakcji łańcucha filtrów z łańcuchem akcji" i sprecyzowali miejsca obu wymienionych części we frameworku MVC.
Jakiś czas temu razem z paroma osobami ze świata napisaliśmy (a oni dalej rozwijają) framework MVC -- Cake php (www.cakephp.org). Rozwiązanie problemu URLi ściągnęliśmy z RoR (www.rubyonrails.org).
Pomysł opiera się na przypisaniu adresów do konkretnych klas i metod, tak, że np. adres:
www.example.com/blog/view/55
odpowiada klasie BlogController (Controller to "C" w "MVC") i metodzie view() w tej klasie, a "55" przekazywane jest jako parametr do wywołania metody, czyli powyższe wywołanie przekształcane jest w:
Kod
print BlogController->view(55);
Reguły przypisania określane są przez mechanizm Router. Można dzięki niemu zmienić rozumienie wywołań w dość dowolny sposób:
Kod
$Router->connect('/', array('controller'=>'Pages', 'action'=>'view', 'home'));
...oznacza, że wywołanie strony głównej (/) uruchamia PagesController->view('home').
Kod
$Router->connect('/kupuj/:action/*', array('controller'=>'Shop', 'action'=>'kategoria'));
...oznacza, że wywołania adresów typu /kupuj, /kupuj/koszyk, /kupuj/kategoria/5, /kupuj/produkt/234/czerwony przekształcane są w wywołania, odpowiednio:
Kod
print ShopController->kategoria();
print ShopController->koszyk();
print ShopController->kategoria(5);
print ShopController->produkt(234, 'czerwony');
Jest do tego manual
Ociu
10.09.2005, 08:29:05
pies: czyli dla każdego modułu musisz tworzyć nowy Controller ? Nie widze najmniejszego sensu.
Mam link w takiej postaci:
/pl/content/home/ - dla strony głównej portalu. Jeśli chce uruchomić np. blog to daje.
/pl/blog/home/
opcjonalnie mam link z parametrem /pl/blog/entry/view,13/ (przykład).
Request: (cząstka)
<?php
public function SimpleVirtualURL() {
$iURL = (isset($_SERVER['PATH_INFO']) ?
$_SERVER['PATH_INFO'] : THRORIN_LINK
); }
?>
Czyli rozbija adres do tablicy. w Routerze jest analizowanie tej tablicy:
<?php
public function Analyse() {
$this->request->SimpleVirtualURL();
$this->lang = (empty($this->request->iURL[1
]) ? THRORIN_LANG
: $this->request->iURL[1
]); $this->system=(empty($this->request->iURL[2]) ?
'content' : $this->request->iURL[2
]); $this->module=(empty($this->request->iURL[3]) ?
'home' : $this->request->iURL[3
]);
$url = explode(',', $this->request->iURL[4
]);
# czyszczenie tablicy iURL
$this->request->iURL = array();
$this->option=$url[0];
$this->id=$url[1];
}
?>
Później Controller wywołuje odpowiednią akcję.
I tak dzięki 4 plikom (+view) mam uniwersalny silnik
pies
12.09.2005, 14:00:38
Cytat
pies: czyli dla każdego modułu musisz tworzyć nowy Controller ? Nie widze najmniejszego sensu.
Nie bardzo rozumiem co masz na myśli. Jeżeli moduł to pojedyncza funkcjonalność serwisu (np. newsy albo obsługa formularza) to w moim modelu moduł nazywa właśnie controller.
Cytat
Później Controller wywołuje odpowiednią akcję.
I tak dzięki 4 plikom (+view) mam uniwersalny silnik

Mój mechanizm działa bardzo podobnie, tylko dodatkowo jest konfigurowalny i ma obsługę błędów (zakładam, że Twój też). Nie wiem z ilu plików się składa, bo jest częścią frameworku i ma trochę zależności (m.in. logowanie błędów), ale ogólnie rzecz biorąc mam klasy Router (konfiguracja URLi) i Dispatcher (odczytuje konfigurację, ładuje potrzebne klasy, tworzy obiekt controllera i uruchamia go).
Konfigurowalność pozwala na dodanie m.in. krótkiego aliasu do jakiejś strony, na przykład
Kod
www.audi.com/a4
które działa tak jak
Kod
www.audi.com/products/view/a4
.
Robi się to tak:
<?php
$Router->connect('/a4', array('controller'=>'Product', 'action'=>'view', 'a4'); ?>
Wywołana będzie metoda ProductController->view('a4').
Ociu
16.09.2005, 12:09:43
Witam,
Cytat
Nie bardzo rozumiem co masz na myśli. Jeżeli moduł to pojedyncza funkcjonalność serwisu (np. newsy albo obsługa formularza) to w moim modelu moduł nazywa właśnie controller.
To już mi się wydaje bardziej logiczne. Coś mi się wcześniej ubzdurało, że controller modułu =/= moduł.
'Błądzić jest rzeczą ludzką.'Cytat
Mój mechanizm działa bardzo podobnie, tylko dodatkowo jest konfigurowalny i ma obsługę błędów (zakładam, że Twój też).
Pewnie, że mam. Mój ErrorHandler jest dostępny na Algorytmy, klasy, funkcje
---
Tak nie mając dostępu do komputera, myślałem, troszke o linkach i stwierdziłem, ze nie ma sensu tworzenia tak długiego linku. Zastosuje się do /module/option/id/, czyli np. /produkty/pokaz/14/.
Aliasy ? hm.. nie głupie, ale. Aliasy są tworzone, dla unikalnych id. A jeśli chciałbyś stworzyć aliasy dla newsów i artykułów ? Wtedy mogą wystąpić takie same id i skrypt się sypie. Oczywiście zakładam dość ekstremalny przypadek, bo raczej nikt nie tworzy aliasów dla newsów i artów, tylko dla sklepów itp. jednak rozpatrzmy wszystkie przypadki

pozdrawiam
pies
16.09.2005, 18:52:00
Cytat
Tak nie mając dostępu do komputera, myślałem, troszke o linkach i stwierdziłem, ze nie ma sensu tworzenia tak długiego linku. Zastosuje się do /module/option/id/, czyli np. /produkty/pokaz/14/.
Czyli jak u mnie /controller/action/id. Moja metoda ma większe możliwości, bo nie ma siły żebyś nie potrzebował zaraz /module/option/id/value i /module/option/id/operation/id2 i tak dalej. U mnie jest to obsługiwane automatycznie (czyli nie stałe id, tylko parametry które option/action przyjmuje jak każda normalna funkcja).
Cytat
Aliasy ? hm.. nie głupie, ale. Aliasy są tworzone, dla unikalnych id. A jeśli chciałbyś stworzyć aliasy dla newsów i artykułów ? Wtedy mogą wystąpić takie same id i skrypt się sypie. Oczywiście zakładam dość ekstremalny przypadek, bo raczej nikt nie tworzy aliasów dla newsów i artów, tylko dla sklepów itp. jednak rozpatrzmy wszystkie przypadki

Nie wiem po co _można_ używać aliasów, ale ja dodałem je dlatego, że używamy tego w serwisach -- jako landing-pages do akcji promocyjnych (np. reklamy w różnych portalach mają różne landing-pages żeby na bieżąco zliczały wejścia) czy jako adresy podawane w reklamach.
Docelowo system aliasów będzie konfigurowalny przez CMS, dlatego musi być dość uniwersalny. Nie wiem jeszcze co z tego wyjdzie
Ociu
17.09.2005, 09:51:17
Cytat(pies @ 2005-09-16 19:52:00)
U mnie jest to obsługiwane automatycznie (czyli nie stałe id, tylko parametry które option/action przyjmuje jak każda normalna funkcja).
Mogłbyś rozwinąć swoją wypowiedź ? najlepiej kodem
Strzałek
19.12.2005, 22:14:36
hmmm, no to wziąłem temat po raz kolejny już na raz przeczytałem i nie wiem już co myśleć. Tyle tutaj mądrości

Więc ja widzę co tak i chcę się upewnić czy dobrze rozumuje:
adres wygląda tak:
http://www.example.com/<action>/<view>/i teraz wchodzimy na stronkę:
http://example.com/: odpalamy dośmyśną akcję i domyślny widok
http://example.com/articles/: odpalamy akcję articles i domyślny widok dla niej
http://example.com/news/showAll/: odpalamy akcję news i widok showAll
http://example.com/news/rss/: odpalamy akcję news i widok rss (wyświtlamy rssy

)
http://example.com/news/pdf/423: odpalamy akcję news i widok pdf oraz dajemy jeszcze na końcu id news'a który ma być wyświtlony w formacie pdf'a

i teraz czy czuję o co biega w tym. Co inaczej powinno to działać ?
Vengeance
19.12.2005, 22:19:03
To ja się dołącze z innym pytaniem. Co zrobić z Apache/php aby takie URLe jak powyżej działały? Co dać w .htaccess aby każdy taki URL odnosił się do
http://example.com/index.phpWażne także by URLe kończące się jakimś rozszerzeniem, lub takie:
http://example.com/katalog/img.jpg?a=tekstnie były przeżucane do index.php ale interpretowane standardowo
FiDO
19.12.2005, 22:56:33
Vengeance: to pytanie nie ma duzego zwiazku z tematem, wiec zadaj je (a w zasadzie znajdz odpowiedz, bo to juz nie raz bylo przerabiane) w opowiednim miejscu, OT tutaj niepotrzebne.
Ociu
20.12.2005, 19:42:05
Strzałek: uruchom admina

Jako, że nabyłem doświadczenia (no dobra, trochę), przebudowałem cały system do takiej postaci:
/module/action/parametr/paratemtr1/parametr2
defaultowo /content/display/news
FilterChain - (klasycznie) kolejka -> ActionChain:
<?php
public function execute( HttpContext $context, FilterChain $chain ) {
$build = $context->module.'_'.$context->method;
$model = new $build();
$model->perform($context->what, $context->vars);
$chain->nextExecute($context);
}
?>
(Uproszczony kod).
noi mam ./modules/content/actions/display.php
<?php
class content_display
public function perform($what, $a = null) {
if($a == null) {
$this->display($what);
} else {
$this->displayByArgs($what, $f);
}
}
?>
Pozwoliło mi to na stworzenie panelu admina
pozdrawiam
Vomit
26.06.2006, 12:02:31
Nie bede zakladal nowego topic'u poniewaz moje pytania(e) dotycza(y) MVC.
Wszystko co wiem o tym wzorcu wiem z mini-frameworka zaprezentowanego niegdys przez hwao. U siebie zrobilem wiec bardzo podobnie, nie wiem jednak jak zaimplementowac akcje i w jaki sposob.
Ludvik
26.06.2006, 12:05:23
Stwórz sobie interfejs dla akcji, który posiada jedną metodę, w której akcja dokonuje wszystkich operacji na danych. Żeby nie była odizolowana od otoczenia przekaż jako argument wszystkie potrzebne informacje z kontekstu (żądanie, obiekt sesji itp.). Akcje lepiej uruchamiać w łańcuchach, więc musisz znaleźć sposób na zapisanie nazwy kolejnej akcji (ja to zapisuję w obiekcie Context). Jeżeli nie ma następnej akcji zapisujesz pusty ciąg znaków. Akcje uruchamiasz w pętli...
Vomit
26.06.2006, 12:15:44
Troszke strasznie to brzmi, cóz bede musial liczyc ze hwao zaimplementuje jeszcze do tego mini frameworka akcje, albo poszukac jakichs przykladow.
Nostress
10.07.2006, 13:02:33
W skrócie, ale od początku:
- Mamy FronController, który uruchamia to, co potrzebne jest każdej akcji.
- Na podstawie danych od użytkownika (np. z URL) uruchamia on odpowiednią akcje (dajmy na to listaNewsow). Tu na chwile praca FrontControllera się kończy, a funkcję określaną jako Controller przejmuje uruchomiona akcja.
- akcja wczytuje plik modelu, pobiera z niego odpowiednie dane (tu: newsy), co może wyglądać tak:
<?php
require_once( 'model' );
class listanewsowAction
{
private model;
public function __construct()
{
$this->model = new Model;
}
public function uruchom()
{
$dane = $this->model->listaNewsow();
}
}
?>
I w tym miejscu mam pewne wątpliwości:
1) czy ta akcja (listanewsowAction) powinna tylko pobrać dane, zwrócić je FrontControllerowi, a ten wybiera odpowiedni widok?
2) czy akcja sama w sobie powinna pobrać dane, wybrać widok i go wyświetlić?
Mam nadzieje, ze napisalem w miare zrozumiale. Główną myślą tego posta jest "jak uruchamiać widok, jak (w którym momencie) decydujemy jak dane wyświetlić (czy to bedzie smarty, pdf czy xml)". Jak wy to robicie? A może zupełnie pomieszałem?
squid
10.07.2006, 13:32:41
Cytat(Nostress @ 10.07.2006, 14:02 )

I w tym miejscu mam pewne wątpliwości:
1) czy ta akcja (listanewsowAction) powinna tylko pobrać dane, zwrócić je FrontControllerowi, a ten wybiera odpowiedni widok?
2) czy akcja sama w sobie powinna pobrać dane, wybrać widok i go wyświetlić?
Mam nadzieje, ze napisalem w miare zrozumiale. Główną myślą tego posta jest "jak uruchamiać widok, jak (w którym momencie) decydujemy jak dane wyświetlić (czy to bedzie smarty, pdf czy xml)". Jak wy to robicie? A może zupełnie pomieszałem?
Wg danymi po pobraniu i przetworzeniu powienien zajac sie Controller (nie koniecznie FrontController), taki kontroler zdecydowalby jaki ma byc format wyjsciowy danych (na podstawie obiektu Request) i zastosowac otrzymane dane do jakiegos szablonu. Na koniec calosc z odpowiednimi naglowkami wyslac do usera.
U mnie kiedy FrontController dostaje spowrotem sterowanie z akcji uruchamia obiekt widoku, ktory sie tym zajmuje.
Ociu
13.07.2006, 08:02:04
Wg. mnie to zależne jest od Ciebie jak framework ma działać.
IMHO FrontController uruchamia model, akcję i widok. Model pobiera dane i robi z nimi jakieś czary, przekazuje akcji, a akcja daje widokowi i mamy wynik.
Levabul
15.07.2006, 11:59:35
To ja zadam pytanie z seri pytań oczywistych (dla innych)

. Przedstawie to obrazowo:
Czy model jest klasą obsługującą np. daną tablę w bazie danych:
<?php
class News extends Model {
protected $tableName = 'news';
protected
$fields = array ('id', 'title', 'author_id', 'date', 'content');
}
$table = new News ();
$table -> WhereAuthor_idEqual('1');
$table -> OrderByIdDesc();
$result = $table -> select ();
?>
Czy może jest klasą mającą na celu np. obsługę newsów (a więc nie tylko tablei news):
<?php
class News extends Model {
protected function getNews () {
$sql = mysql_query ('SELECT `id`, `title`, `date`, `content`, `users`.`name` as author FROM `news` IN
NER JOIN `users` ON `author_id` = `users`.`id` ORDER BY id DESC'); $result[] = $row;
}
return $row;
}
#funkcja wykozystywana przez kontroler do pobierania danych od modeli
public function get () {
$data = $this -> getNews ();
return $data;
}
}
?>
mariuszn3
15.07.2006, 12:08:40
Te wszystkie klasy należą do modelu. Model jest to wewnętrzna logika aplikacji, włącznie z częścią komunikującą się z bazą danych. Zazwyczaj część odpowiadającą za komunikację z bazą danych wydorębnia się w modelu (w moduł DAO - data access object) ale nadal logicznie rzecz ujmując jest to część modelu. Przynajmniej ja to tak rozumiem.
squid
15.07.2006, 13:12:49
Jesli moge zastapic slowo model akcja to akcja ma za zadanie wykonac operacje na danych nie dbajac gdzie i jak sa zapisane oraz jakiego sa formaty (no oczywiscie w pewnych granicach). Jak dobijasz sie dodanych to juz raczej nie ejst sprawa modelu, mozesz zastowosowac metode aktywnego rekordu, jakas abstrakcje w stylu PEAR::MDB lub SDO i inne wynalazki.
Vomit
26.07.2006, 22:00:24
Witam,
Wydaje mi sie ze w moim projekcie udało mi sie zaimplementowac wzorzec MVC, moze nie dokladnie i nie idealnie ale przeciez nie o to chodzi, trzeba korzystac z pasujacych nam rozwiazan a nie wdrazac je na sile.
Doszedlem jednak do pewnego momentu, ktory zainteresowal mnie. Router rozbija URL i zwraca jako tablice. Pierwszy element tablicy to moduł, ktory ma zostac "odpalony". Wszystko jest przemyslane i dobrze dziala, ale teraz mam dobudowac jeszcze jeden, administracje.
Nie moze byc on wlaczany na tych samych prawach jak inne moduły. Znajduje sie on w innym folderze, w innym folderze beda jego szablony. Zle by bylo przeciez gdy w folderze styli byly default, jakisinny, styl_do_admina.
W moim projekcie FrontController, to glowna klasa zarzadzajaca modulami do wczytania. Jak zastrzec ze modul 'admin' ma byc traktowany w inny sposob?
Nie chodzi mi oczywiscie o to zebyscie powiedzieli "potraktuj to if'em" bo tak mozna najprosciej. Chodzi mi o to jak wy robicie to u siebie.
squid
26.07.2006, 22:39:00
Nie jestem pewien czy Router powinien rozbijac URL na tablice, wydaje mi sie ze to Geqest powinien to robic a na Router spada odpowiedzialnosc za dostarczenie mechanizmu tworzenia linkow i dostarczenia info o akcji jaka zostala zarzadana.
Nie wiem czy dobrze rozumiem ale czy pytasz o autoryzacje? Czy chcesz wiedziec czy uzytkownik X ma prawo wykonac akcje Y? Ja to robie w ten sposob, ze te akcje, ktore maja ograniczona liczbe uzytkownikow (np. akcje administracyjne) przed swoim wykonaniem musza wykonac akcje autoryzacyjna, ktora jest zwykla akcja tyle tylko ze jesli stwierdzi ze user X nie ma prawa wykonac akcji Y to rzuci wyjatkiem a do wykonania zarzadanej akcji nie dojdzie. Daje mi to duza elastycznosc co do wyboru metody i algorytmu autoryzacji, wszysko mam w jednym miejscu i cokolwiek by sie nie zmienilo wystarczy ze zmienie jedna akcje aby dostosowac sie np. do LDAP'a
mariuszn3
26.07.2006, 22:42:59
Ja w ogóle rozdzieliłem kontroler części administracyjnej i użytkownika (apache jest u mnie front controllerem).
W konfiguracji http ustawiłem też aby część adminstracyjna serwisu była dostępna pod innym portem przykładowo 8100. Natomiast w katalogu htdocs mam dwa podkatalogi 'user' i 'admin'. kiedy użytkownik wchodzi poprzez tradycyjne 'www.mojadomena.com' apache przekierowuje na kontroler w katalogu 'user' a kiedy wchodzi na 'www.mojadomena.com:8100' apache przekierowuje na kontroler w katalogu 'admin'.
Oczywiście aby dokładnie tak to załatwić trzeba mieć pełny dostęp do konfiguracji apache'a.. ale ogólnie idea jest taka, że wydzieliłem osobne ścieżki na część użytkownika i administratora co oczywiście nie przeszkadza im korzystać z tych samych modułów.
Vomit
26.07.2006, 22:51:00
Squid: zle zrozumiales, fakt, autoryzacja bedzie kolejnym krokiem, ale chodzi mi wlasnie o to o czym mowi mariuszn3.
Rozdzielenie czesci administracyjnej od czesci uzytkownika. Poczynajac wlasnie od kontrolera. Rozwiazanie ciekawe, ale wymaga jak juz napisał dostepu do Apache'a.
NuLL
26.07.2006, 23:25:24
Witam,
Cytat
Rozdzielenie czesci administracyjnej od czesci uzytkownika
Chyba nic trudnego w stworzeniu dla kazdej akcji prostego configu z opisem do ktorej czesci aplikacji nalezy

Pozdr.
Vomit
26.07.2006, 23:37:30
Ano nic trudnego, ale nie chce poprostu aby w folderze ktorym trzymane sa moduly byl takze trzymany admin a tpl'ki od admina lezaly w folderze reszty strony.
Niby blahy problem, ale nie chce robic w rodku Frontcontrollera if'a if ( $module == 'admin' ) to odczytuj z innego folderu ;p
NuLL
26.07.2006, 23:43:17
Vomit - nie rozumiem twojego podejscia - moze napisz sobie osobna aplikacje administracyjna
mariuszn3
26.07.2006, 23:43:22
front controler to raczej same if'y i switch'e, więc co zaszkodzi dodać jeszcze jeden

Reasumując jeśli nie możesz go zastąpić apachem to chyba nie ma miejsca na inne rozwiązanie.
Denver
27.07.2006, 06:51:09
Ja, gdy chcę mieć pewność, że uruchomine zostaną tylko i wyłącznie te moduły, które chcę, sprawdzam zawsze, czy mam je zapisane w jakiejś tablicy. Przykładowo:
<?php
$arrModules = array ('kontakt', 'galeria', 'rekrutacja', 'uslugi'); $arrAdminModules = array ('admin');
// Zmienna $strModule została nam przekazana z jakiegoś kontrolera, który odczytał
ją ze zmiennych GET/POST
{
// Uruchom dane akcje modułu
}
elseif (in_array ($strModule, $arrAdminModules)) {
// Uruchom panel administracyjny
}
else
{
throw new Exception ('Ten moduł nie jest obsługiwany');
}
?>
Oczywiście w panelu administracyjnym należy sprawdzić uprawnienia użytkownika do danych sekcji. Ja zazwyczaj trzymam uprawnienia w bazie, więc każdy moduł sprawdza sobie dane flagi przypisane konkretnemu użytkownikowi. Jeśli dostęp powinien być zabroniony, wyrzucam wyjątek i cześć.
squid
27.07.2006, 13:08:35
Cytat(Vomit @ 26.07.2006, 23:51 )

Rozdzielenie czesci administracyjnej od czesci uzytkownika. Poczynajac wlasnie od kontrolera. Rozwiazanie ciekawe, ale wymaga jak juz napisał dostepu do Apache'a.
Ja nie rozdzielam, nie wydaje mi sie aby to byl dobry pozmysl rozdzielac cos co z zasady ma byc jedno. Po co rozdzielac kontroler aplikacji skoro on ma kontrolowac przeplyw miedzy innymi czesciami aplikacji i w zasadzie na tym koniec. Dostajesz zapytanie ?action=x i kontroler przekazuje sterowanie do odpowiedniej metody i nie martwi sie o to co to jest x, moze sprawdzic czy istnieje ale to wszystko.
Ociu
27.07.2006, 13:10:05
Może poprostu pobawić się uprawnieniami ?
bigZbig
27.07.2006, 13:34:12
Ja nie wydzielam czesci administracyjnej. U mnie administrator widzi ten sam widok co zwykly user z tym wyjatkiem ze tam gdzie trzeba administratorowi pojawiaja sie jeszcze np. linki edit, delete, add itp. Wymaga to uzycia paru ifow, ale jest bardzo wygodne podczas pracy. Ogladajac cos jako uzytkownik nieraz zauwazam ze cos trzeba zmienic. W takiej sytuacji nie musze sie zastanawiac gdzie to mam w panelu administracyjnym. Zwyczajnie loguje sie jako admin (nie musze nawet przechodzic pomiedzy stronami bo skrypt logowania przekierowuje mnie spowrotem w miejsce z ktorego wyszlo zadanie logowania) i pojawia mi sie odsylacz edit. Prosto i wygodnie. Nie trzeba robic osobnych tplkow poza formularzami.
Denver
27.07.2006, 14:14:58
Popieram przedmówcę - to bardzo wygodne rozwiązanie. Logowanie przekierowuje do strony, która nas do ostatnio oglądanej strony, i te 2 IF-y w szablonach nie mają wpływu na wydajność skryptu. Szablon sprawdza mi uprawnienia danego użytkownika (odwołując się do obiektu User w którym przechowuję te uprawnienia) i jeśli np. użytkownik ma uprawnienie edycji newsów, to koło nagłówka wiadomości pokazuje się link do jej edycji.
Prosto i przyjemnie
br-design.pl
26.08.2006, 22:00:41
Cytat(bigZbig @ 27.07.2006, 14:34 )

Ja nie wydzielam czesci administracyjnej. U mnie administrator widzi ten sam widok co zwykly user z tym wyjatkiem ze tam gdzie trzeba administratorowi pojawiaja sie jeszcze np. linki edit, delete, add itp. Wymaga to uzycia paru ifow, ale jest bardzo wygodne podczas pracy. Ogladajac cos jako uzytkownik nieraz zauwazam ze cos trzeba zmienic. W takiej sytuacji nie musze sie zastanawiac gdzie to mam w panelu administracyjnym. Zwyczajnie loguje sie jako admin (nie musze nawet przechodzic pomiedzy stronami bo skrypt logowania przekierowuje mnie spowrotem w miejsce z ktorego wyszlo zadanie logowania) i pojawia mi sie odsylacz edit. Prosto i wygodnie. Nie trzeba robic osobnych tplkow poza formularzami.
Wszedlem na forum zeby wlasnie zadac to pytanie, super rozwiazanie, ALE, przeciez nie mozna wszystkiego tym rozwiazac, sa inne rzeczy niz tresc strony (np. administracja uzytkownikami, czy np. zamowienia w sklepie) , ktorych user nie widzi, wiec bez panela sie nie obejdzie.
Tak czy siak wracamy do problemu jak rozdzielic panel w MVC. Ja sklaniam sie do zrobienia osobnego frontcontrollera w katalogu admin (w glownym pliku htaccess dac regule ze przekierowania z domena.com/admin kierowac do katalogu admin gdzie czeka juz inny front controller niz domyslny), wtedy controllery, widoki trzymac w osobnych podkatalogach, ale z drugiej strony panel admina powinien moc korzystac z tych samych modeli co controllery glowne (userowe ze tak powiem).
Co o tym myslicie?
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.