![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
![]() Grupa: Przyjaciele php.pl Postów: 742 Pomógł: 0 Dołączył: 14.12.2003 Skąd: Gdańsk, Trójmiasto Ostrzeżenie: (0%) ![]() ![]() |
Router to obiekt który rozbija żądanie i wyciąga z niego nazwę żądanej akcji, parametry itp. Router jest także generatorem linków (np nice urls)
HttpRequest jest obiektem, bedącym otoczką dla żądania http. I teraz moje pytania: 1. Czy HttpRequest powinien by jednocześnie routerem: Kod --- klient --- czy router powinien byc oddzielny analizowac dane z httpRequest i na tej podstawie stwierdzac, którą ma akcję uruchomic:--- HttpRequest i Router w jednym --- --- kontroler - pobiera nazwe akcji z Routera --- Kod --- klient --- ?--- HttpRequest --- --- Router - analizuje HttpRequest sprawdzająca jaka akcja ma byc uruchomiona --- --- Kontroler - pobiera z routera nazwe akcji --- 2. Jeżeli ta pierwsza opcja to gdzie tu powinien by generator linków? Przecież nie za bardzo pasuje on do HttpRequest |
|
|
![]()
Post
#2
|
|
![]() Grupa: Zarejestrowani Postów: 358 Pomógł: 0 Dołączył: 3.07.2003 Skąd: Szczecin->niebuszewo->*(next to window) Ostrzeżenie: (0%) ![]() ![]() |
Cytat(aleksander @ 2005-07-21 15:41:19) czy router powinien byc oddzielny analizowac dane z httpRequest i na tej podstawie stwierdzac, którą ma akcję uruchomic: Kod --- klient --- ?--- HttpRequest --- --- Router - analizuje HttpRequest sprawdzająca jaka akcja ma byc uruchomiona --- --- Kontroler - pobiera z routera nazwe akcji --- a co bys chcial zeby HttpRequest robil (troche konkretniej) -------------------- Jeśli życie to kara to nieźle nabroiłem ;-)
|
|
|
![]()
Post
#3
|
|
![]() Grupa: Przyjaciele php.pl Postów: 742 Pomógł: 0 Dołączył: 14.12.2003 Skąd: Gdańsk, Trójmiasto Ostrzeżenie: (0%) ![]() ![]() |
no HttpRequest jest otoczką dla rządania http, ma metody pozwalające na wyciągnięcie danych POST GET COOKIE FILES.
Po prostu mam kilka argumentów jedne na to, żeby HR i Router były połączen drugie na nie i nie wiem co lepsze, więc pytam się Was:) |
|
|
![]()
Post
#4
|
|
Grupa: Przyjaciele php.pl Postów: 7 494 Pomógł: 302 Dołączył: 31.03.2004 Ostrzeżenie: (0%) ![]() ![]() |
Ostatnio zainteresowałem się Mojavi. Tam HttpRequest i Ruter (w zasadzie nie wystepuje on jawnie) nie są w żadnym razie połączone.
Dla mnie ideałem jest: 1. HR jest odpowiedzialne za żądanie aplikacji (parametry POST, GET, ...) i posiada metody do manipulacji nimi. 2. Router w rzeczywistości służy tylko do pobrania nazwy akcji z żądania i przekazanie tej informacji do Kontrolera 3. Kontroler rozdziela zadania, na podstawie informacji od Rutera i to on powinien zawierać metody do generowania linków. W modelu tym bez wachania mozna pominąć Ruter, gdyż jest tylko ogniwem przekazującym dane i nie wnosi nic do aplikacji. Dane z HR Kontroler może sobie sam pobrać bez przeszkód:
... czy jakoś tak. Kontroler wcale nie potrzebuje tutaj Rutera. Jeżeli miałby on się jednak znaleść to napewno cząść Kontrolera, ale z pewnością nie część HR. Tak funkcjonuje framework Mojavi, który moim zdaniem jest baaardzo bliski ideałowi. |
|
|
![]()
Post
#5
|
|
![]() Developer Grupa: Moderatorzy Postów: 2 844 Pomógł: 20 Dołączył: 25.11.2003 Skąd: Olkusz ![]() |
Moze troche byc zle napisane bo nie oto chodzi. Mysle ze imho tak to powinno wygladac, czemu? Mozna dopisac sobie np request z lini polecen ConsoleRequest nie trzeba calosci przerabiac. Mysle ze Router nie powinien dziedziczyc z request (podobnie request z routera) tutaj lepszym rozwiazaniem jest agregacja (zawieranie). Request jest poto zeby z niego dziedziczyc. Daje to jako taka swobode dzialania. Jak ktos ma ciekwasze pomysly to z checia obejrze. Router w tym ukladzie dostarcza informacji kontrolerowi co i jak... |
|
|
![]()
Post
#6
|
|
Grupa: Przyjaciele php.pl Postów: 7 494 Pomógł: 302 Dołączył: 31.03.2004 Ostrzeżenie: (0%) ![]() ![]() |
Cytat(hwao @ 2005-07-21 21:37:39) (...) Mysle ze imho tak to powinno wygladac, czemu? Mozna dopisac sobie np request z lini polecen ConsoleRequest nie trzeba calosci przerabiac. (...) Request jest poto zeby z niego dziedziczyc. Dokladnie o to chodzi i to jest siłą takiego rozwiązania. Hierarchia może wtedy wyglądać tak: Class Request Cytat(hwao @ 2005-07-21 21:37:39) (...) Router w tym ukladzie dostarcza informacji kontrolerowi co i jak... W zasadzie, jak już wspomniałem, jest on zbędnym przekaźnikiem. Nie wnosi nic konkretnego poza kolejną warstwą przez którą sie trzeba przebić w poszukiwaniu danych o żądaniu aplikacji. ak dla mnie może on istnieć jako część (metodda, lub jakiś mały obiekcik) Kontrolera. Ale najlepiej to by było, jakby go nie było ![]() Przecią Kontroler sam może sobie dane pobrać z Requesta (a dokładnie z klasy dziedzczącej po nim). |
|
|
![]()
Post
#7
|
|
![]() Grupa: Zarejestrowani Postów: 358 Pomógł: 0 Dołączył: 3.07.2003 Skąd: Szczecin->niebuszewo->*(next to window) Ostrzeżenie: (0%) ![]() ![]() |
Cytat(hwao @ 2005-07-21 22:37:39)
Request jest poto zeby z niego dziedziczyc. Daje to jako taka swobode dzialania. Czemu wiec request jako klasa abstrakcyjna a nie interfejs? wtedy klasa httpRequest moglaby implementowac metody wspolne dla wszystkich mozliwych rodzajow requestow z interfesu Request i metody specyficzne dla tego protokolu jak implementacja interfejsu HTTP Ten post edytował squid 3.08.2005, 13:20:17 -------------------- Jeśli życie to kara to nieźle nabroiłem ;-)
|
|
|
![]()
Post
#8
|
|
![]() Grupa: Zarejestrowani Postów: 362 Pomógł: 0 Dołączył: 18.02.2004 Skąd: Knurów Ostrzeżenie: (0%) ![]() ![]() |
Sam zastanawiam się teraz nad tym problemem. U mnie cala operacja wygląda tak:
Mam klasę HttpRequest, która implementuje interfejs iHttpRequest. W konstruktorze klasy HttpRequest mam takie coś:
i tak dalej dla Cookie, Files, itp. Klasa GetParametersContainer wygląda tak:
Teraz najlogiczniejszym IMO umiejscowieniem routera będzie klasa GetParametersContainer i nowa klasa HttpRequest. Np. tworzę sobie klasę RoutedGetParamterersContainer, która będzie odpowiednio rozszyfrowywala PATH_INFO. Potem tworzę sobie klasę RoutedHttpRequest rozszerzającą HttpReqest i imlpementującą interfejs iHttpRequest, która w konstruktorze zawiera zamiast:
to
Dzięki temu do zmiennych Get mogę odwolywać się tak jak zawsze mimo, że przechodzą one przez router. |
|
|
![]()
Post
#9
|
|
![]() Grupa: Zarejestrowani Postów: 521 Pomógł: 0 Dołączył: 3.11.2003 Skąd: 3city Ostrzeżenie: (0%) ![]() ![]() |
Dla mnie funkcje requesta to:
- wymuszanie, żeby dostęp do danych POST, GET itd był tylko przez tą klasę - nie można zmieniać np. danych POST, bo request na to nie pozwala - można wymienić klasę requesta i np. wczytać wszystkie dane z pliku XML (dobre do testowania) - można dołożyć jakieś filtry na requesta, np. odtegować magic_quotes_gpc - jest to dobre miejsce do jakiejś analizy danych wejściowych Funkcje routera: tylko jedna, ale bardzo ważna: zamiana URLi na nazwy akcji i z powrotem. Mojavi nie zawiera routera, i przez to schemat URLi musi być zakodowany na sztywno w kontrolerze. Router i request powinny być IMHO rozdzielone, bo zadania mają inne. Jeszcze co do requesta: Jest to bardzo praktyczna i wygodna rzecz. Gdyby ktoś zrobił request w ramach SPL, to wziąłbym go bez zastanawiania się. Problem w tym, że ciężko dojść do porozumienia, jakie dokładnie metody powinien zawierać, i jest to zawsze kawałek kodu, który nie jest niezbędny. Więc chyba najlepiej jest go zaimplementować tak, żeby narzut czasowy i ilość kodu były minimalne. |
|
|
![]()
Post
#10
|
|
Grupa: Przyjaciele php.pl Postów: 7 494 Pomógł: 302 Dołączył: 31.03.2004 Ostrzeżenie: (0%) ![]() ![]() |
Cytat(hawk @ 2005-07-22 09:16:43) Mojavi nie zawiera routera, i przez to schemat URLi musi być zakodowany na sztywno w kontrolerze. Tak to wygląda w Mojavi, (kawałek klasy WebController)
Stała MO_URL_FORMAT jest definiowana w pliku konfiguracyjnym, a możliwość rozszerzenia tej funkcji ogromne. Więc niby zaszyte ale nie tak bardzo sztywno ![]() O.T. Przepraszam za nieustanną propagandę Mojavi ale jakoś mnie ten framework zafascynował, jest bardzo przejrzyście i ładnie napisany. I dlatego można go sobie w banalny sposób przebudować i dostosować do swoich upodobań. Pewnie ma jakieś wady, ale nie znalazłem jeszcze większych/rażących ![]() |
|
|
![]()
Post
#11
|
|
![]() Grupa: Zarejestrowani Postów: 521 Pomógł: 0 Dołączył: 3.11.2003 Skąd: 3city Ostrzeżenie: (0%) ![]() ![]() |
Wiem, sam uważnie studiowałem Mojavi
![]() 1) Jak chcę, żeby mój URL wyglądał inaczej, to muszę grzebać w kodzie samego frameworka. Co praktycznie wyklucza taką możliwość. 2) Zwiększanie liczby opcji też nie jest dobre, bo php będzie musiał parsować np. kilkanaście różnych if...else parsujących URL, kiedy przez cały czas używana jest tylko jedna opcja - niepotrzebny kod. |
|
|
![]()
Post
#12
|
|
Grupa: Przyjaciele php.pl Postów: 7 494 Pomógł: 302 Dołączył: 31.03.2004 Ostrzeżenie: (0%) ![]() ![]() |
Przyznają rację - jest to niedogodność.
P.S. Zauważyłeś jeszcze jakieś bugi/biedogodności w Mojavi. Bo ja chyba tylko jeszcze jedną. Ale to rozmowa na inny temat lub na PW. Nie zanieczyszczajmy wątku bo schodzimy z tematu ![]() |
|
|
![]()
Post
#13
|
|
![]() Grupa: Zarejestrowani Postów: 362 Pomógł: 0 Dołączył: 18.02.2004 Skąd: Knurów Ostrzeżenie: (0%) ![]() ![]() |
Ale wciąż mam wątpliwości co do tego Routera. Jeśli mamy linki postaci:
index.php/module/test/action/test/p1/blah/p2/test To HttpRequest nie będzie mial żadnych zmiennych w tablicy $_GET, a IMO powinien mieć. Powinien rozszyfrować ten url i mieć 4 zmienne: module, action, p1 i p2. Router zaś powinien chyba zapytać HttpRequest o zmienne module i action i podać je kontrolerowi. Albo powinien mieć możliwość zmiennych GET klasy HttpRequest, tak, aby w dalszej części skryptu byly normalnie dostępne przez HttpRequest. |
|
|
![]()
Post
#14
|
|
![]() Grupa: Zarejestrowani Postów: 521 Pomógł: 0 Dołączył: 3.11.2003 Skąd: 3city Ostrzeżenie: (0%) ![]() ![]() |
Nie powinien mieć. To router powinien wiedzieć, że nie szukamy zmiennych w tablicy GET, tylko bierzemy REQUEST_URI (czy jak to się nazywało) z SERVER i tniemy na kawałki. Request powinien tylko dostarczać wszystkie te dane tak, jak były one ustawione przez serwer http, bez interpretowania ani szukania w nich module/action.
W każdym razie takie jest moje zdanie. Nigdzie nie jest napisane, że nie może być inaczej, ale tak wydaje mi się lepiej. Wtedy zmiana schematu URLi == zmiana routera, a request zostaje bez zmian. |
|
|
![]()
Post
#15
|
|
![]() Grupa: Zarejestrowani Postów: 362 Pomógł: 0 Dołączył: 18.02.2004 Skąd: Knurów Ostrzeżenie: (0%) ![]() ![]() |
Cytat(hawk @ 2005-07-22 14:41:55) Nie powinien mieć. To router powinien wiedzieć, że nie szukamy zmiennych w tablicy GET, tylko bierzemy REQUEST_URI (czy jak to się nazywało) z SERVER i tniemy na kawałki. Request powinien tylko dostarczać wszystkie te dane tak, jak były one ustawione przez serwer http, bez interpretowania ani szukania w nich module/action. W każdym razie takie jest moje zdanie. Nigdzie nie jest napisane, że nie może być inaczej, ale tak wydaje mi się lepiej. Wtedy zmiana schematu URLi == zmiana routera, a request zostaje bez zmian. A dajmy na to w Phiend2, Router mialby być ladowany przed BasicHttpRequest (i czytać bezpośrednio z tablicy $_SERVER), czy po i przyjmować jako argument instancję klasy implementującej iHttpRequest i z niej pobierać informacje z tablicy $_SERVER? A co jeśli mamy caly URL w techinice NiceURL, czyli dajmy na to: index.php/a/1/b/2/c/3 HttpRequest ma nie wiedzieć o tym, że te dane z PATH_INFO są zastępstwem zwyklych danych z tablicy $_GET? W takim razie jak w innej części kodu mamy pobrać wartość zmiennej a, b lub c? Mi się wydawalo najrozsądniej w kodzie wyciągnąć z kontekstu (Context) instancje iHttpRequest i poprosić ją o te zmienne. A jak Ty to widzisz? |
|
|
![]()
Post
#16
|
|
![]() Grupa: Zarejestrowani Postów: 521 Pomógł: 0 Dołączył: 3.11.2003 Skąd: 3city Ostrzeżenie: (0%) ![]() ![]() |
W phiend2 (dokładnie: w phiend.mvc) router jest po request. Przyjmuje jako argument i wyciąga takie dane, jakie chce.
Co do wyciągania później zmiennych, widzę 2 sposoby: 1) router może zwrócić nazwę akcji + parametry, więc jedna implementacja routera może przepisać te parametry z tablicy GET, a druga na podstawie PATH_INFO 2) sama akcja może odwołać się bezpośrednio do requesta i wyciągnąć potrzebne parametry Ale tutaj widzę pewien problem, i pewnie o to Tobie chodziło: jeżeli schemat URLi dyktuje nie tylko, jak wyciągać z URLa nazwę akcji, ale także, jak uzyskać inne parametry potrzebne konkretnej akcji, akcja nie powinna odwoływać się bezpośrednio do requesta, bo nie wie, jak są te parametry zakodowane. W tej sytuacji widzę 3 wyjścia: 1) zrobić requesta, który potrafi w ograniczonym zakresie przetwarzać dane wejściowe (nie szuka nazwy akcji, ale przepisuje parametry z PATH_INFO do GET, jeżeli trzeba), i podmienić zamiast BasicHttpRequest 2) zrobic routera, który będzie w stanie zorientować się, że dana akcja potrzebuje parametrów, i wyciągnąć je zgodnie z przyjętym schematem URLi 4) router zawsze bierze wszystkie dodatkowe parametry GET (lub wszystko, co zostaje w PATH_INFO) i podaje akcji jako parametry, a akcja niech sama się martwi, które z nich naprawdę były jej potrzebne |
|
|
![]()
Post
#17
|
|
![]() Grupa: Zarejestrowani Postów: 362 Pomógł: 0 Dołączył: 18.02.2004 Skąd: Knurów Ostrzeżenie: (0%) ![]() ![]() |
Dokladnie o twoją 1 propozycję chodzilo mi w tym poście. Osobiście wolę przerzucić wyciąganie potrzebnych parametrów na akcje niż pchać je na silę przez Router
![]() IMO najlepszym wyjściem jest po prostu tworzenie nowej klasy implementującej interfejs iHttpRequest, a router ograniczyć do pobierania od tej klasy informacji o bieżącej akcji/module. |
|
|
![]()
Post
#18
|
|
![]() Grupa: Zarejestrowani Postów: 657 Pomógł: 2 Dołączył: 15.08.2003 Skąd: Łódź Ostrzeżenie: (0%) ![]() ![]() |
Ponieważ każdy widział kod phiend2, to wszystko będzie pod jego "logike" tak by łatwiej było się dogadać :]
Kod url1: site.org/modul/akcja/param1/param2/param3 url2: site.org?m=modul&a=akcja&1=param1&2=param2&3=param3 W zaleznosci ktory Request wybierzemy, rozbija on podane URLe na tablice: Kod array[m] = modul array[a] = akcja array[1] = param1 array[2] = param2 array[3] = param3 Akcje pobieraja sobie te dane bezpośrednio:
I teraz podstawowe pytanie... gdzie w cały schemat klas umiejscowić Router (Jak zwał tak zwał) bym mógł szybko generować URLe dla dowolnego schematu. Przypuśmy że w kodzie TPL potrzebuje zrobić: Kod <a href="{funkcja_smarty(array('m'=>modul2,'a'=>akcja2,1=>param1))}">Inna akcja i modul niz obecnie wywolane</a> Albo w kodzie akcji:
Więc jak tu dobrze umiejscowić ROuter by móc się do niego wygodnie odwoływać z Szablonów czy też akcji w celu stworzenia URLa ?! -------------------- |
|
|
![]()
Post
#19
|
|
![]() Grupa: Zarejestrowani Postów: 521 Pomógł: 0 Dołączył: 3.11.2003 Skąd: 3city Ostrzeżenie: (0%) ![]() ![]() |
Żeby to dobrze działało, router i request musiałyby być "zsynchronizowane". Tzn jeżeli request bierze parametry z GET, to router tworzy urle wykorzystując GET. A to mi śmierdzi, bo dwa komponenty muszą mieć wspólny sposób obsługi. Zgodnie z prawem Murphiego... Jakieś pomysły?
|
|
|
![]()
Post
#20
|
|
![]() Grupa: Zarejestrowani Postów: 657 Pomógł: 2 Dołączył: 15.08.2003 Skąd: Łódź Ostrzeżenie: (0%) ![]() ![]() |
@hawk: nie koniecznie, Request może rozbijać PATH_INFO by np. obsłużyć pokazany wyżej url1, a Router będzie tablicę podaną w parapetrze join-ował ze znakiem '/'. Tylko mnie chodzi o to, jak połączyć Router z innymi klasami, by łatwo było go wymieniać, ale i łatwy był dostęp z TPL czy z akcji do niego. Kompletnie nie wiem pod co pasuje ficzer "generowania urli" tym bardziej ze jest to potrzebne w wielu miejsach
-------------------- |
|
|
![]() ![]() |
![]() |
Aktualny czas: 21.08.2025 - 10:00 |